python - 将 gui 中的函数分离到进程中。滞后

标签 python interface pyqt pyqt5

首先我创建了代码的功能部分,后来决定向其添加一个接口(interface),因此我将接口(interface)和之前代码的主要功能链接起来,如下所示。

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(921, 988)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)
        self.verticalLayout.setObjectName("verticalLayout")
        self.sheet2 = QtWidgets.QLabel(self.centralwidget)
        self.sheet2.setObjectName("sheet2")
        self.verticalLayout.addWidget(self.sheet2)
        self.sheet1 = QtWidgets.QLabel(self.centralwidget)
        self.sheet1.setObjectName("sheet1")
        self.verticalLayout.addWidget(self.sheet1)
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 921, 21))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        # self.label_2.setText(_translate("MainWindow", "TextLabel"))
        # self.label.setText(_translate("MainWindow", "TextLabel"))

class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.setupUi(self)

    def update_sheet2(self, Image):
        qim = ImageQt(Image)
        pix = QtGui.QPixmap.fromImage(qim)
        pix = pix.scaled(self.sheet2.width(), self.sheet2.height(), QtCore.Qt.KeepAspectRatio)
        self.sheet2.setPixmap(pix)
        self.sheet2.setAlignment(QtCore.Qt.AlignCenter)

    def update_sheet1(self, Image):
        qim = ImageQt(Image)
        pix = QtGui.QPixmap.fromImage(qim)
        pix = pix.scaled(self.sheet1.width(), self.sheet1.height(), QtCore.Qt.KeepAspectRatio)
        self.sheet1.setPixmap(pix)
        self.sheet1.setAlignment(QtCore.Qt.AlignCenter)


def run_ui():
    import sys
    app = QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    w.show()
    w.background = main(w)
    t = Process(target=w.background.process)
    t.start()
    sys.exit(app.exec_())

这段代码中名为main(ui)的函数中,使用ui的代码如下。我使用 run_ui() 函数来运行代码

def main(ui):
    for i in range(100000000):
        x=1
        y = x*x*x
    img = Image.open('XXX.png'.format(GRAY_PATH,1))
    ui.update_sheet1(img)


if __name__ == '__main__':
    run_ui()

我已将 ui 'w' 作为参数传递给主函数,它使用该引用来调用包含图像数据的 update_sheet1,2 函数。

这会滞后 GUI,并且它总是不响应,并且图像也不会出现在 GUI 上。

我认为这与我喜欢界面的方式有关。但不知道如何解决它。

感谢您的帮助。

最佳答案

Qt 不支持多处理,因此为了消除问题的复杂性,请使用线程。在这种情况下,Qt 还指示不应从另一个线程修改 GUI,而不是我创建一个 QObject 并将其导出到另一个线程,这个 QObject 有一个传输图像的信号。

另一方面,当您执行 main(w) 时,您将调用主进程中的繁重任务,这会导致 GUI 卡住,而您必须传递函数的名称以及该函数的参数参数数量:

from PyQt5 import QtCore, QtGui, QtWidgets
from PIL import Image
from PIL.ImageQt import ImageQt
from threading import Thread

# ...

class Signaller(QtCore.QObject):
    imageSignal = QtCore.pyqtSignal(Image.Image)


class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.setupUi(self)

    def update_sheet2(self, Image):
        # ...

    @QtCore.pyqtSlot(Image.Image)
    def update_sheet1(self, Image):
        qim = ImageQt(Image)
        pix = QtGui.QPixmap.fromImage(qim)
        pix = pix.scaled(self.sheet1.width(), self.sheet1.height(), QtCore.Qt.KeepAspectRatio)
        self.sheet1.setPixmap(pix)
        self.sheet1.setAlignment(QtCore.Qt.AlignCenter)


def run_ui():
    import sys
    app = QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    w.show()
    signaller = Signaller()
    signaller.imageSignal.connect(w.update_sheet1)
    t = Thread(target=main, args=(signaller,), daemon=True)
    t.start()
    sys.exit(app.exec_())


def main(signaller):
    for i in range(100000000):
        x=1
        y = x*x*x
    img = Image.open('XXX.png')
    signaller.imageSignal.emit(img)


if __name__ == '__main__':
    run_ui()

关于python - 将 gui 中的函数分离到进程中。滞后,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55844169/

相关文章:

python - 我想模拟打开一个现有的测试文件,对其应用一个函数进行测试,但不更改文件的实际内容

java - 在java中没有这样的关键字的静态接口(interface)和普通接口(interface)有什么区别?

python - PyQtGraph 图形布局小部件问题

python - 如何将变量从 PyQt5 UI 返回到 Main 函数 - Python

python - 如何从字典创建数据框

python - 使用cx_freeze后QGraphicsPixmapItem不会出现

python - 按列 NAME dtype 选择列

c++ - 使用抽象类的容器来容纳子类

go - 试图将文字转换为 Golang 中的指针

python - PYQT:QSqlTableModel。如何过滤数字而不是文本