将 Pyqt GUI 主应用程序作为单独的非阻塞进程运行 [英] Run Pyqt GUI main app as a separate, non-blocking process

查看:85
本文介绍了将 Pyqt GUI 主应用程序作为单独的非阻塞进程运行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

我已经使用线程实现了这个解决方案(运行 pyQT GUI main应用程序在单独的线程中),正如评论中预测的那样,它在几个周期后崩溃了 python 控制台.

这是试点代码:

导入系统从 PyQt5 导入 QtWidgets、QtGui、QtCore类 MainWindow(QtWidgets.QWidget):def __init__(self):# 调用超类构造函数super(MainWindow, self).__init__()# 一一构建对象布局 = QtWidgets.QVBoxLayout(self)self.pb_load = QtWidgets.QPushButton('Load')self.pb_clear= QtWidgets.QPushButton('清除')self.edit = QtWidgets.QTextEdit()layout.addWidget(self.edit)layout.addWidget(self.pb_load)layout.addWidget(self.pb_clear)# 将回调连接到按钮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('你好世界')def callback_pb_clear(self):self.edit.clear()定义我的线程():app = QtWidgets.QApplication(sys.argv)赢 = 主窗口()赢.show()app.exec_()定义显示():进口螺纹t = threading.Thread(target = mythread)t.daemon = 真t.start()如果 __name__ == '__main__':app = QtWidgets.QApplication(sys.argv)赢 = 主窗口()赢.show()sys.exit(app.exec_())

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

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

解决方案

线程在这里无关紧要.PyQt 已经被设计为在普通的 Python 交互式会话中工作,因此不需要做任何特殊的事情来使其工作.

我建议你删除 mythreadshow 函数并用这样的东西替换它们:

如果 QtWidgets.QApplication.instance() 是 None:app = QtWidgets.QApplication(sys.argv)

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

<预><代码>>>>从 mygui 导入 MainWindow>>>赢 = 主窗口()>>>赢.show()>>>win.callback_pb_load()

永远不要调用 app.exec_().PyQt 会自己处理事件循环.

I'm looking for the possibility of running a pyqt GUI from the python or ipython console.

Basically the main idea is to use the Pyqt GUI like one would use a matplotlib plot or image, where you pass arguments to a GUI from the console to look at data, continue to do stuff in the console, maybe open another window, close the first one, do more stuff in the console and so on.

I've implemented this solution using threading (Run pyQT GUI main app in seperate Thread), and as predicted in the comments it crashes the python console after a few cycles.

Here is the pilot code:

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_())

Running the file would run the GUI normally. Importing it and then run show() would attempt to run the GUI from the console in a non-blocking manner.

Is there a way to spawn a thread or process embedding the PyQt app that would behave like a matplotlib window would ?

解决方案

Threading is irrelevant here. PyQt is already designed to work in a normal python interactive session, so there is no need to do anything special to make it work.

I would suggest you remove the mythread and show functions and replace them with something like this:

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

Then you can use your gui module like this:

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

Do not ever call app.exec_(). PyQt will take care of the event-loop itself.

这篇关于将 Pyqt GUI 主应用程序作为单独的非阻塞进程运行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆