将gui的功能分离到过程中。滞后的

时间:2019-04-25 07:39:46

标签: python interface pyqt pyqt5

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

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上。

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

感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

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