将 Pyqt GUI 主应用程序作为单独的非阻塞进程运行

Posted

技术标签:

【中文标题】将 Pyqt GUI 主应用程序作为单独的非阻塞进程运行【英文标题】:Run Pyqt GUI main app as a separate, non-blocking process 【发布时间】:2017-11-15 14:13:03 【问题描述】:

我正在寻找从 python 或 ipython 控制台运行 pyqt GUI 的可能性。

基本上,主要思想是使用 Pyqt GUI,就像使用 matplotlib 绘图或图像一样,您将参数从控制台传递给 GUI 以查看数据,继续在控制台中执行操作,也许打开另一个窗口,关闭第一个,在控制台中做更多的事情等等。

我已经使用线程 (Run pyQT GUI main app in seperate Thread) 实现了这个解决方案,并且正如 cmets 中预测的那样,它在几个周期后崩溃了 python 控制台。

这是试点代码:

import sys
from PyQt5 import QtWidgets, QtGui, QtCore

class MainWindow(QtWidgets.QWidget):
    def __init__(self):
        # call super class constructor
        super(MainWindow, self).__init__()
        # build the objects one by one
        layout = QtWidgets.QVBoxLayout(self)
        self.pb_load = QtWidgets.QPushButton('Load')
        self.pb_clear= QtWidgets.QPushButton('Clear')
        self.edit = QtWidgets.QTextEdit()
        layout.addWidget(self.edit)
        layout.addWidget(self.pb_load)
        layout.addWidget(self.pb_clear)
        # connect the callbacks to the push-buttons
        self.pb_load.clicked.connect(self.callback_pb_load)
        self.pb_clear.clicked.connect(self.callback_pb_clear)

    def callback_pb_load(self):
        self.edit.append('hello world')
    def callback_pb_clear(self):
        self.edit.clear()

def mythread():
    app = QtWidgets.QApplication(sys.argv)
    win = MainWindow()
    win.show()
    app.exec_()

def show():
    import threading
    t = threading.Thread(target = mythread)
    t.daemon = True
    t.start()

if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    win = MainWindow()
    win.show()
    sys.exit(app.exec_())

运行文件将正常运行 GUI。导入它然后运行 ​​show() 将尝试以非阻塞方式从控制台运行 GUI。

有没有办法生成嵌入 PyQt 应用程序的线程或进程,其行为类似于 matplotlib 窗口?

【问题讨论】:

【参考方案1】:

线程在这里无关紧要。 PyQt 已经被设计成可以在普通的 python 交互会话中工作,所以不需要做任何特别的事情来让它工作。

我建议您删除 mythreadshow 函数并将它们替换为以下内容:

if QtWidgets.QApplication.instance() is None:
    app = QtWidgets.QApplication(sys.argv)

然后你可以像这样使用你的 gui 模块:

>>> from mygui import MainWindow
>>> win = MainWindow()
>>> win.show()
>>> win.callback_pb_load()

永远不要打电话给app.exec_()。 PyQt 会处理事件循环本身。

【讨论】:

请注意,如果您想在 IPython 中执行此操作,则必须以 ipython --gui=qt5 开头,或者在启动 IPython 后键入 %gui qt5 当然,我认为我的主要问题一直是尝试使用 ipython 来执行此操作,而没有 %gui qt5 修饰符。按照上面的食谱可以正常工作。已解决,谢谢。

以上是关于将 Pyqt GUI 主应用程序作为单独的非阻塞进程运行的主要内容,如果未能解决你的问题,请参考以下文章

当阻塞任务与 GUI 相关时,如何保持 PyQt GUI 响应?

Python 3.5,单独窗口中的 pyqt5 进度条 gui

从 Frida 的非主线程调用 API 来修改应用程序的 GUI

使用 QProcess 通过 PyQt 运行和监控系统进程

需要 PyQt5 GUI 结构建议

基于multiprocessing和threading实现非阻塞的GUI界面显示