线程函数块 main 并不总是
Threading function block main not all the time
我正在开发一个项目,其中有一个 main class,它创建一个线程来执行一个很长的函数,而 main class(我的 GUI)将继续可用在这个长函数的执行过程中显示一些信息。所以我在 Stack Overflow 上找到了一种方法:
from PyQt5 import QtWidgets, QtCore, QtGui
from PyQt5.QtWidgets import QApplication
import threading
import sys
import time
from PyQt5.QtCore import QObject, pyqtSignal
class Ui_SaftMainWindow(object):
def setupUi(self, SaftMainWindow):
SaftMainWindow.setObjectName("SaftMainWindow")
SaftMainWindow.resize(178, 284)
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap(":/logo/img_Logo-E.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
SaftMainWindow.setWindowIcon(icon)
self.gridLayout = QtWidgets.QGridLayout(SaftMainWindow)
self.gridLayout.setObjectName("gridLayout")
self.frame_all_pb = QtWidgets.QFrame(SaftMainWindow)
self.frame_all_pb.setMinimumSize(QtCore.QSize(160, 0))
self.frame_all_pb.setMaximumSize(QtCore.QSize(160, 16777215))
self.frame_all_pb.setObjectName("frame_all_pb")
self.gridLayout_7 = QtWidgets.QGridLayout(self.frame_all_pb)
self.gridLayout_7.setObjectName("gridLayout_7")
self.pb_stop_simu = QtWidgets.QPushButton(self.frame_all_pb)
self.pb_stop_simu.setText("STOP")
self.gridLayout_7.addWidget(self.pb_stop_simu, 5, 0, 1, 1)
self.pb_start_simu = QtWidgets.QPushButton(self.frame_all_pb)
self.pb_start_simu.setObjectName("pb_start_simu")
self.pb_start_simu.setText("START")
self.gridLayout_7.addWidget(self.pb_start_simu, 4, 0, 1, 1)
self.gridLayout.addWidget(self.frame_all_pb, 0, 0, 1, 1)
QtCore.QMetaObject.connectSlotsByName(SaftMainWindow)
class Solver(QObject, object):
data_changed = pyqtSignal(str, int)
def __init__(self):
# Call init function of QObject class for pyQt signal
QObject.__init__(self)
def init_parameters(self, input_files, **keys):
print("Some initialisation")
def time_step(self):
# Function with Fortran call
print("Fortran function")
def transient_solve(self, arg):
print("starting")
t = threading.currentThread()
i = 1
while getattr(t, "do_run", True):
print("working on " + str(i))
i += 1
time.sleep(5)
print("Stopping as you wish.")
class GuiHandler:
def __init__(self, gui, main_window,):
# Declarations
self.gui = gui
self.main_window = main_window
self.gui.setupUi(self.main_window)
self.gui.pb_start_simu.clicked.connect(self.pb_start_simu_clicked)
self.gui.pb_stop_simu.clicked.connect(self.pb_stop_simu_clicked)
# Create instance of the second class
app = Solver()
# Connect signal to emit signal from second class to ihm later
app.data_changed.connect(self.myfunction)
# Initialize some parameters of my second class
app.init_parameters("", json_file="", output_file="")
# Create thread object
self.t = threading.Thread(target=app.transient_solve, args=("task",))
def pb_start_simu_clicked(self):
print("Start thread")
self.t.start()
def pb_stop_simu_clicked(self):
print("Stop thread")
self.t.do_run = False
self.t.join()
def myfunction(self, string="this_is_a_test", integer=0):
print(str(string))
print(str(integer))
if __name__ == "__main__":
app = QApplication(sys.argv)
handler = GuiHandler(Ui_SaftMainWindow(), QtWidgets.QWidget())
handler.main_window.show()
sys.exit(app.exec_())
这个简单的例子有效。但是,当我通过调用更大的函数(调用编译为 Python 的 Fortran 文件的 time_step 函数替换睡眠时,GUI 函数被阻止)
知道它是否与我创建和启动线程的方式有关,或者知道我必须 check/find 使我的代码正常工作吗?
我现在不能给你另一个代码示例。
我找到了解决办法,在fortran代码中加入!f2py: threadsafe
。
我正在开发一个项目,其中有一个 main class,它创建一个线程来执行一个很长的函数,而 main class(我的 GUI)将继续可用在这个长函数的执行过程中显示一些信息。所以我在 Stack Overflow 上找到了一种方法:
from PyQt5 import QtWidgets, QtCore, QtGui
from PyQt5.QtWidgets import QApplication
import threading
import sys
import time
from PyQt5.QtCore import QObject, pyqtSignal
class Ui_SaftMainWindow(object):
def setupUi(self, SaftMainWindow):
SaftMainWindow.setObjectName("SaftMainWindow")
SaftMainWindow.resize(178, 284)
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap(":/logo/img_Logo-E.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
SaftMainWindow.setWindowIcon(icon)
self.gridLayout = QtWidgets.QGridLayout(SaftMainWindow)
self.gridLayout.setObjectName("gridLayout")
self.frame_all_pb = QtWidgets.QFrame(SaftMainWindow)
self.frame_all_pb.setMinimumSize(QtCore.QSize(160, 0))
self.frame_all_pb.setMaximumSize(QtCore.QSize(160, 16777215))
self.frame_all_pb.setObjectName("frame_all_pb")
self.gridLayout_7 = QtWidgets.QGridLayout(self.frame_all_pb)
self.gridLayout_7.setObjectName("gridLayout_7")
self.pb_stop_simu = QtWidgets.QPushButton(self.frame_all_pb)
self.pb_stop_simu.setText("STOP")
self.gridLayout_7.addWidget(self.pb_stop_simu, 5, 0, 1, 1)
self.pb_start_simu = QtWidgets.QPushButton(self.frame_all_pb)
self.pb_start_simu.setObjectName("pb_start_simu")
self.pb_start_simu.setText("START")
self.gridLayout_7.addWidget(self.pb_start_simu, 4, 0, 1, 1)
self.gridLayout.addWidget(self.frame_all_pb, 0, 0, 1, 1)
QtCore.QMetaObject.connectSlotsByName(SaftMainWindow)
class Solver(QObject, object):
data_changed = pyqtSignal(str, int)
def __init__(self):
# Call init function of QObject class for pyQt signal
QObject.__init__(self)
def init_parameters(self, input_files, **keys):
print("Some initialisation")
def time_step(self):
# Function with Fortran call
print("Fortran function")
def transient_solve(self, arg):
print("starting")
t = threading.currentThread()
i = 1
while getattr(t, "do_run", True):
print("working on " + str(i))
i += 1
time.sleep(5)
print("Stopping as you wish.")
class GuiHandler:
def __init__(self, gui, main_window,):
# Declarations
self.gui = gui
self.main_window = main_window
self.gui.setupUi(self.main_window)
self.gui.pb_start_simu.clicked.connect(self.pb_start_simu_clicked)
self.gui.pb_stop_simu.clicked.connect(self.pb_stop_simu_clicked)
# Create instance of the second class
app = Solver()
# Connect signal to emit signal from second class to ihm later
app.data_changed.connect(self.myfunction)
# Initialize some parameters of my second class
app.init_parameters("", json_file="", output_file="")
# Create thread object
self.t = threading.Thread(target=app.transient_solve, args=("task",))
def pb_start_simu_clicked(self):
print("Start thread")
self.t.start()
def pb_stop_simu_clicked(self):
print("Stop thread")
self.t.do_run = False
self.t.join()
def myfunction(self, string="this_is_a_test", integer=0):
print(str(string))
print(str(integer))
if __name__ == "__main__":
app = QApplication(sys.argv)
handler = GuiHandler(Ui_SaftMainWindow(), QtWidgets.QWidget())
handler.main_window.show()
sys.exit(app.exec_())
这个简单的例子有效。但是,当我通过调用更大的函数(调用编译为 Python 的 Fortran 文件的 time_step 函数替换睡眠时,GUI 函数被阻止)
知道它是否与我创建和启动线程的方式有关,或者知道我必须 check/find 使我的代码正常工作吗?
我现在不能给你另一个代码示例。
我找到了解决办法,在fortran代码中加入!f2py: threadsafe
。