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

Python 将gui中的功能分离到流程中。滞后,python,interface,pyqt,pyqt5,Python,Interface,Pyqt,Pyqt5,首先,我创建了代码的功能部分,后来决定向其中添加一个接口,因此我将该接口与前面代码的主要功能链接起来,如下所示 class Ui_MainWindow(object): def setupUi(self, MainWindow): MainWindow.setObjectName("MainWindow") MainWindow.resize(921, 988) self.centralwidget = QtWidgets.QWidget(

首先,我创建了代码的功能部分,后来决定向其中添加一个接口,因此我将该接口与前面代码的主要功能链接起来,如下所示

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\u 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'作为参数传递给main函数,它使用该引用调用带有图像数据的update_sheet1,2函数

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

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


谢谢你的帮助

Qt不支持多处理,因此要消除问题的复杂性,请使用线程。在本例中,Qt还指示不应从另一个线程修改GUI,而不是创建QObject并将其导出到另一个线程,该QObject具有传输图像的信号

另一方面,当您执行main(w)时,您正在调用主进程中的繁重任务,这会导致GUI冻结,相反,您必须通过以下参数传递函数名和该函数的参数:

从PyQt5导入QtCore、QtGui、qtwidget
从PIL导入图像
从PIL.ImageQt导入ImageQt
从线程导入线程
# ...
等级信号员(QtCore.QObject):
imageSignal=QtCore.pyqtSignal(Image.Image)
类MainWindow(QtWidgets.QMainWindow,Ui_MainWindow):
def uuu init uuu(self,parent=None):
超级(主窗口,自我)。\uuuuu初始化\uuuuuuu(父级)
self.setupUi(self)
def更新表2(自身,图像):
# ...
@pyqtSlot(Image.Image)
def更新表1(自身,图像):
qim=ImageQt(图像)
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():
导入系统
app=qtwidts.QApplication(sys.argv)
w=主窗口()
w、 show()
信号员
信号器.图像信号.连接(w.update_表1)
t=Thread(target=main,args=(signaller,),daemon=True)
t、 开始()
sys.exit(app.exec_())
def主(信号机):
对于范围内的i(100000000):
x=1
y=x*x*x
img=Image.open('XXX.png')
信号器.图像信号.发射(img)
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
运行_ui()

Qt不支持多处理,因此要消除问题的复杂性,请使用线程。在本例中,Qt还指示不应从另一个线程修改GUI,而不是创建QObject并将其导出到另一个线程,该QObject具有传输图像的信号

另一方面,当您执行main(w)时,您正在调用主进程中的繁重任务,这会导致GUI冻结,相反,您必须通过以下参数传递函数名和该函数的参数:

从PyQt5导入QtCore、QtGui、qtwidget
从PIL导入图像
从PIL.ImageQt导入ImageQt
从线程导入线程
# ...
等级信号员(QtCore.QObject):
imageSignal=QtCore.pyqtSignal(Image.Image)
类MainWindow(QtWidgets.QMainWindow,Ui_MainWindow):
def uuu init uuu(self,parent=None):
超级(主窗口,自我)。\uuuuu初始化\uuuuuuu(父级)
self.setupUi(self)
def更新表2(自身,图像):
# ...
@pyqtSlot(Image.Image)
def更新表1(自身,图像):
qim=ImageQt(图像)
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():
导入系统
app=qtwidts.QApplication(sys.argv)
w=主窗口()
w、 show()
信号员
信号器.图像信号.连接(w.update_表1)
t=Thread(target=main,args=(signaller,),daemon=True)
t、 开始()
sys.exit(app.exec_())
def主(信号机):
对于范围内的i(100000000):
x=1
y=x*x*x
img=Image.open('XXX.png')
信号器.图像信号.发射(img)
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
运行_ui()

提供一个新的选项。Qt不支持多处理,因此您不应该从另一个进程修改GUI。“这可能就是延迟的原因。”eyllanesc,好的,我将写一个更短的主函数,其中包含相关的部分。我很快就会更改,这样你就可以看到是否可以。出于明显的原因,将
Process(target=w.background.Process)
更改为
Process(target=w.background)
img=Image.open('XXX.png'.format(GRAY_PATH,1))
更改为
img=Image.open('XXX.png')
。因此,您的代码不是mcvestll lags,代码仍在做完全相同的事情。如何指出您的代码不是MCVE,因为它不会重现您的问题,并提供一个解决方案。Qt不支持多处理,因此您不应该从另一个进程修改GUI。“这可能就是延迟的原因。”eyllanesc,好的,我将写一个更短的主函数,其中包含相关的部分。我很快就会更改,这样你就可以看到是否可以。出于明显的原因,将
Process(target=w.background.Process)
更改为
Process(target=w.background)
img=Image.open('XXX.png'.format(GRAY_PATH,1))
更改为
img=Image.open('XXX.png')
。因此,您的代码不是McVestll lags,代码仍在做完全相同的事情如何指出您的代码不是MCVE,因为它不会重现您的问题谢谢您的帮助,但我想问,这是否真的有必要为loop提供此答案。@Eshaka是的,因为您在出版物中的句子可以让您思考得非常清楚