将 wxPython 与 GLCanvas 一起使用时,鼠标单击事件被阻止

问题描述 投票:0回答:1

我创建了一个 wxPython 应用程序并在 wxFrame 中放置了一个 GLCanvas。我已经将EVT_LEFT_DOWN事件绑定到GLCanvas,但是运行程序时,鼠标单击事件似乎没有实时响应。必须等到程序关闭才能看到点击的事件都打印在一起了

感觉主线程的mainLoop阻塞了鼠标点击事件。我该如何调整来解决这个问题,您有什么建议吗?

我添加了一个额外的代码片段。我在 macOS 上使用 Python 版本 3.10、wxPython 版本 4.2.1 和 PyOpenGL 版本 3.1.7 运行代码。

import wx
from wx import glcanvas
from OpenGL.GL import *
import random


class MyCanvas(glcanvas.GLCanvas):
    def __init__(self, parent):
        glcanvas.GLCanvas.__init__(self, parent, -1)
        self.context = glcanvas.GLContext(self)

        self.Bind(wx.EVT_PAINT, self.on_paint)
        self.Bind(wx.EVT_LEFT_DOWN, self.on_left_down)

    def on_left_down(self, event):
        x, y = event.GetPosition()
        print(f"Mouse clicked at ({x}, {y})")

    def on_paint(self, event):
        dc = wx.PaintDC(self)
        self.SetCurrent(self.context)
        self.on_draw()

    def on_draw(self):
        glClearColor(random.randrange(256)/255, random.randrange(256)/255, random.randrange(256)/255, 1.0)
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
        self.SwapBuffers()


def main():
    app = wx.App()
    frame = wx.Frame(None)
    sizer = wx.BoxSizer()
    frame.SetSizer(sizer)
    canvas = MyCanvas(frame)
    sizer.Add(canvas, 1, wx.EXPAND)
    frame.Show()
    app.MainLoop()


if __name__ == '__main__':
    main()

Here is a demonstration of the above code's execution.

multithreading wxpython glcanvas
1个回答
0
投票

我怀疑问题出在你用来在调试模式下运行代码的任何东西。

从命令行运行它,避免使用调试/开发工具。

import wx
from wx import glcanvas
from OpenGL.GL import *
import random


class MyCanvas(glcanvas.GLCanvas):
    def __init__(self, parent):
        glcanvas.GLCanvas.__init__(self, parent, -1)
        self.context = glcanvas.GLContext(self)

        self.Bind(wx.EVT_PAINT, self.on_paint)
        self.Bind(wx.EVT_LEFT_DOWN, self.on_left_down)
        self.Bind(wx.EVT_RIGHT_DOWN, self.on_right_down)
        self.Bind(wx.EVT_LEFT_UP, self.on_left_up)
        self.Bind(wx.EVT_MOTION, self.on_mouse_motion)
        self.Bind(wx.EVT_LEFT_DCLICK, self.on_dclick)
        self.Bind(wx.EVT_MOUSEWHEEL, self.on_scroll)

    def on_left_down(self, event):
        self.x, self.y = event.GetPosition()
        print(f"Mouse click Down at ({self.x}, {self.y})")
        self.Refresh(False)


    def on_right_down(self, event):
        self.x, self.y = event.GetPosition()
        print(f"Mouse Right click Down at ({self.x}, {self.y})")

    def on_dclick(self, event):
        print(f"Mouse Doubled Clicked")
        event.Skip()

    def on_left_up(self, event):
        self.x, self.y = event.GetPosition()
        print(f"Mouse click Released at ({self.x}, {self.y})")

    def on_mouse_motion(self, event):
        if event.Dragging() and event.LeftIsDown():
            prev_x, prev_y = self.x, self.y
            self.x, self.y = event.GetPosition()
            print(f"Mouse movement from ({prev_x, prev_y}) to ({self.x, self.y})")
            self.Refresh(False)

    def on_scroll(self, event):
        up_down = event.GetWheelRotation()
        if up_down < 1:
            print(f"Mouse scroll Down")
        else:
            print(f"Mouse scroll Up")


    def on_paint(self, event):
        dc = wx.PaintDC(self)
        self.SetCurrent(self.context)
        self.on_draw()

    def on_draw(self):
        glClearColor(random.randrange(256)/255, random.randrange(256)/255, random.randrange(256)/255, 1.0)
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
        self.SwapBuffers()


def main():
    app = wx.App()
    frame = wx.Frame(None)
    sizer = wx.BoxSizer()
    frame.SetSizer(sizer)
    canvas = MyCanvas(frame)
    sizer.Add(canvas, 1, wx.EXPAND)
    frame.Show()
    app.MainLoop()


if __name__ == '__main__':
    main()

© www.soinside.com 2019 - 2024. All rights reserved.