对于这个最小的例子,我们有一个主窗口和一个qdialog窗口。每个都有一个按钮。
当用户单击主窗口的按钮时,qdialog窗口将打开。
当用户点击qdialog的按钮时,我想在主窗口中以多处理(异步(的方式运行一个函数。但取而代之的是,它再次打开了一个新的主窗口。
代码:
无标题.py
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'untitled.ui'
#
# Created by: PyQt5 UI code generator 5.15.4
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(318, 41)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
self.gridLayout.setObjectName("gridLayout")
self.open_dialog = QtWidgets.QPushButton(self.centralwidget)
self.open_dialog.setObjectName("open_dialog")
self.gridLayout.addWidget(self.open_dialog, 0, 0, 1, 1)
MainWindow.setCentralWidget(self.centralwidget)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.open_dialog.setText(_translate("MainWindow", "Open Dialog"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
对话框.py
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'dialog.ui'
#
# Created by: PyQt5 UI code generator 5.15.4
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(400, 41)
self.gridLayout = QtWidgets.QGridLayout(Dialog)
self.gridLayout.setObjectName("gridLayout")
self.call_method_button = QtWidgets.QPushButton(Dialog)
self.call_method_button.setObjectName("call_method_button")
self.gridLayout.addWidget(self.call_method_button, 0, 0, 1, 1)
self.retranslateUi(Dialog)
QtCore.QMetaObject.connectSlotsByName(Dialog)
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
self.call_method_button.setText(_translate("Dialog", "Call method from main Window"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
Dialog = QtWidgets.QDialog()
ui = Ui_Dialog()
ui.setupUi(Dialog)
Dialog.show()
sys.exit(app.exec_())
main.py
from PyQt5 import QtCore, QtGui, QtWidgets
import sys
from untitled import *
from dialog import Ui_Dialog
from dialog_code import Dialog_Code
class MainCode:
def __init__(self):
self.app = QtWidgets.QApplication(sys.argv)
self.mainWindow = QtWidgets.QMainWindow()
self.main_ui = Ui_MainWindow()
self.main_ui.setupUi(self.mainWindow)
self.mainWindow.show()
self.main_ui.open_dialog.clicked.connect(self.open_dialog_window)
sys.exit(self.app.exec_())
def open_dialog_window(self):
self.dialog_window = QtWidgets.QDialog(self.mainWindow)
self.ui_dialog_window = Ui_Dialog()
self.ui_dialog_window.setupUi(self.dialog_window)
self.dialog_window.show()
dialog_window_run_code = Dialog_Code(self)
def print_ok_123(self):
print("print_ok_123 method")
for i in range(0,10):
print("Ok")
return 1
program = MainCode()
dialog_code.py
from multiprocessing import Pool
class Dialog_Code:
def __init__(self,main_self):
print("Dialog init")
self.main_self = main_self
self.main_self.ui_dialog_window.call_method_button.clicked.connect(lambda:self.call_main_method())
def call_main_method(self):
print("Button pressed")
self.pool = Pool(processes=1)
result = self.pool.apply_async(self.main_self.print_ok_123, tuple(), self.print_ok_end_123)
self.pool.close()
self.pool.join()
def print_ok_end_123(self):
print("End of main method")
要运行代码,请运行python main.py
pool语句出了什么问题,我该如何修复它?
如果您正在调用一个除self
之外不带其他参数的辅助函数,并且愿意阻塞直到返回结果,那么使用方法apply
:会更简单
result = self.pool.apply(self.main_self.print_ok_123)
这相当于以这种方式使用非阻塞apply_async
:
async_result = self.pool.apply_async(self.main_self.print_ok_123)
# block until the result is ready and get the result:
result = async_result.get()
关键是调用self.pool.apply_async(self.main_self.print_ok_123)
不会从调用self.main_self.print_ok_123
中产生返回值,而是一个AsyncResult
实例,您必须调用其get
方法才能获得实际返回值。因此,尽管对self.pool.close()
和self.pool.join()
的调用将被阻塞,直到所有未完成的任务都完成为止,但如果不在AsyncResult
对象上调用get
,就无法从对self.main_self.print_ok_123
的调用中获得实际返回值。
此外,如果您现在使用方法apply
,根据定义,它会阻塞直到任务完成,严格来说,您不必调用close
和join
。如果你现在想强制清理你的池,你可以调用self.pool.terminate()
,或者当不再有任何引用时,你可以等待池被垃圾收集。
更新
import multiprocessing as mp
class Foo():
@staticmethod
def work1():
return 1
def work2(self):
return 2
if __name__ == '__main__':
pool = mp.Pool(1)
foo = Foo()
print(pool.apply(foo.work1))
print(pool.apply(foo.work2))
打印
1
2