【问题标题】:PyQt: app.exec_() stops all following code from runningPyQt:app.exec_() 停止运行以下所有代码
【发布时间】:2023-03-24 21:40:01
【问题描述】:

我的代码如下所示:

app = QApplication(sys.argv)
self.interface = Interface()

# The figure
self.fig = self.interface.fig
self.ax = self.fig.add_subplot(111)

self.interface.show()
app.exec_()

print 'this is not printed'

问题是一旦app.exec_() 被执行,在我关闭弹出的窗口之前什么都没有。

如何继续运行代码?

【问题讨论】:

    标签: python pyqt pyqt4


    【解决方案1】:

    这是故意的。您需要做的是在调用 app.exec() 之前使用信号/插槽、Qt 类中的代码或生成线程。

    信号和槽是您与 Qt 交互的实际方式。基本上,信号是任何“事件”或自定义“事件”,并且可以将插槽视为“事件处理程序”。例如,当有人点击 GUI 上的按钮时,它会创建一个信号来寻找与其连接的任何处理程序。您可以为每个信号连接一个、一个或多个插槽(您甚至可以多次连接同一个插槽)! Here is a good reference 在 python 中用于此。

    在您的 Qt 类中编码通常意味着创建对您有用的插槽。请记住,您不想将事件循环拖得太久,因此如果您这样做,请生成一个新线程。

    您可以使用的第三个选项是分拆其他线程。小心从线程与 Qt 交互,如果你这样做,你必须使用信号和槽。将线程实现为suggested in this SO

    【讨论】:

    • 我很抱歉,但我对此很陌生,所以您能否更详细地解释一下我应该做什么,或者至少指出一些在线示例?不幸的是,PyQt 示例非常稀缺......
    • 如果您遇到更多麻烦,请告诉我。基本上 app.exec() 应该锁定所有内容,您必须解决它。
    • 所以底线,没有机会运行代码超过app.exec_()?是否可以只打开一个窗口,做一些事情,关闭它,然后运行代码过去?
    • 我从来没有做过,但所有的都表明是的,只要确保你用来关闭它的任何东西都会调用正确的 Qt 信号来关闭它。否则 Qt 会非常混乱地关闭,您可能无法返回该函数。
    【解决方案2】:

    app.exec_() 不锁定任何东西,它运行一个 GUI 事件循环,等待用户操作(事件)并将它们分派到正确的小部件进行处理。它会这样做,直到没有打开的顶层窗口;如果您至少打开应用程序的一个顶级窗口,则 exec() 永远不会返回,它不能(您的应用程序将在系统关闭期间终止)。当没有更多的顶级窗口时,应用程序会清理并从exec() 返回。此时,GUI 不再处于事件循环中。

    无论您想在exec() 之后做什么,您都可能会将其放在 QThread 或信号处理程序中(例如,您将连接到“Go!”按钮;您将连接关闭应用程序窗口的处理程序的“取消”按钮)。

    您可以在exec() 之后添加代码,但这会非常规:如果出现任何问题,用户不太可能看到问题,因为 GUI 不再可见,GUI 应用程序通常没有控制台终端在可能出现错误的地方打开,通常不会有 GUI 应用程序的控制台(即,您将通过 pythonw.exe 而不是 python.exe 运行应用程序),或者您必须打开一个新窗口并再次 exec()为了显示错误消息并等待用户单击确定,请在 ok 处理程序中销毁消息窗口,以便 app.exec() 再次返回。

    【讨论】:

    • gui启动后是否有信号触发?
    • QApplication 发出了十几个信号,其中一个可能会起作用 (doc.qt.io/qt-5/qapplication.html)。可能有一些 QMainWindow 的事件方法(其中大部分在 QWidget 中定义)您可以捕获(通过覆盖方法)。在 SO 上发布特定问题以获取更多详细信息。
    【解决方案3】:

    除了上一个答案之外,并非每次关闭所有窗口时都会停止由app.exec_() 运行的 GUI 事件循环。如果您想手动终止它,您可以在任何事件处理程序中使用app.quit()。它会停止 GUI 事件循环并在 app.exec_() 之后启动您的代码。

    第一个答案是无所事事。

    【讨论】:

      【解决方案4】:

      消除阻塞的一个肮脏技巧是滥用 mathplot lib:

      import matplotlib
      import matplotlib as mpl
      
      import matplotlib.cbook as cbook
      import matplotlib.collections as mcol
      import matplotlib.patches as mpatches
      import matplotlib.mlab as mlab
      import matplotlib.pyplot as plt
      import matplotlib.cm as cm       # colors 
      from   mpl_toolkits.mplot3d import Axes3D   # imports options for 3-D plotting
      from   matplotlib.backends.backend_pdf import PdfPages
      
      from PyQt5 import QtWidgets, uic
      # ============================================================== 
      if not QtWidgets.QApplication.instance():
          app = QtWidgets.QApplication(sys.argv)
      else:
          app = QtWidgets.QApplication.instance() 
      #endelse
      
      MainWindow =  QtWidgets.QMainWindow()
      MainWindow=uic.loadUi('E:\Python\Python_lib\MyGui.ui',MainWindow)
      MainWindow.show()
      
      # There are two ways to start the gui, and i.e. it looping 
      # The correct way if to use app.exec_(), which 
      # blocks the command line :
      
      
      #d=app.exec_()
      
      # However, this will block the command line making 
      # We can misuse mathplot lib creating a Figure instead
      # which seems to start the Gui loop without blocking the command line: 
      
      ImageFig = Figure((3,4))
      ImagePanel = FigureCanvas(ImageFig)
      ImagePanel.draw()
      

      【讨论】:

        猜你喜欢
        • 2021-05-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多