Я пытаюсь улучшить существующую структуру GUI на основе pyQT. GUI - это многопоточный GUI, основанный на pyQT. Я взял часть этого здесь, чтобы объяснить проблему
GUI .py - основной python скрипт, который вызывает функцию для создания вкладки в GUI
from TabWidgetClass import ConstructGUITabs
class mainWindow(QtGui.QMainWindow):
def __init__(self,**kwargs):
super().__init__()
self.dockList = []
#Lets build&run GUI
self.BuildRunGUI() ### initialize GUI
def BuildRunGUI(self):
### frame, status definition
### tab definition
self.mainWidget = QtGui.QTabWidget(self)
self.setCentralWidget(self.mainWidget)
self.GUIConnect = ConstructGUITabs(docklist=self.dockList, parent_widget=self.mainWidget,mutex=self.mutex)
self.show()
if __name__ == "__main__":
try:
mW = mainWindow()
mW.setGeometry(20, 30, 1920*0.9,1080*0.9)
mW.setTabPosition(QtCore.Qt.AllDockWidgetAreas, QtGui.QTabWidget.North)
#mW.show()
TabWidgetClass. py - Сценарий для создания вкладок и виджетов
from SerialInterface import SerialInterface
from BackQThread import BackQThread
class ConstructGUITabs():
def __init__():
super().__init__() #init!!
#Thread Variables
self.main_thread = None
self.background_thread = None
# Let's define each tab here
self.ADD_CALIBRATE_TAB()
############## Start of ADD_CONNECT_TAB##################################################
def ADD_CALIBRATE_TAB(self, tec_layout):
#Create threads here. Main to handle update in GUI & Background thread for few specific
#time consuming operation
self.main_thread = SerialInterface()
self.background_thread = BackQThread()
#Get button connect to get_value through main thread
self.get_button = QtGui.QLabel(self)
self.set_button = QtGui.QPushButton('Set')
self.set_button.clicked.connect(self.set_value)
#Set button connect to Set_value through background_thread
self.get_button = QtGui.QLabel(self)
self.get_button = QtGui.QPushButton('Get')
self.get_button.clicked.connect(self.get_new_value)
self.pwr_disp_val = QtGui.QLineEdit(self)
self.pwr_disp_val.setText('')
#add the layout
#connect signal for backgrund thread
self.background_thread.read_info_flash.connect(self.update_info_from_flash)
def set_value(self):
self.main_thread.setvalue()
def get_new_value(self):
self.background_thread.call_update_info_bg_thread(flag = 'ReadSignalInfo',
list=[var1, var2])
def update_info_from_flash(self,flashData):
self.pwr_disp_val.setText(flashData)
Два библиотечных модуля SerialInterface и BackQThread, как показано ниже:
SerialInterface.py
import pyftdi.serialext
class LaserSerialInterface(object):
def __init__():
self.port = pyftdi.serialext.serial_for_url('COM1',
baudrate=9600,
timeout=120,
bytesize=8,
stopbits=1,
parity='N',
xonxoff=False,
rtscts=False)
def setValue(self, value):
self.port.write(value)
def readvalue(self,value):#nITLA
return (value * 100)
BackQThread.py
from SerialInterface import SerialInterface
class BackQThread(QtCore.QThread):
signal = QtCore.pyqtSignal(object)
read_info_flash = QtCore.pyqtSignal(object)
def __init__(self):
self.serial = SerialInterface()
def call_update_info_bg_thread(self,flag,**kwargs): #nITLA
self.flag = flag
self.kwargs = kwargs
def update_info_bg_thread(self, Signallist): #nITLA
flashData = []
for index in range(0, len(Singnallist)):
flashData.append(self.serial.readvalue(Signallist[index]))
self.read_info_flash.emit(flashData)
def run(self):
while True:
time.sleep(0.1)
if self.flag == None:
pass
elif self.flag == 'ReadSignalInfo':
self.update_info_bg_thread(Signallist = self.kwargs['Signallist'])
self.flag = False
Все вышеперечисленные интерфейсы работают без проблем.
Новое требование - автоматизация GUI. Таким образом, выполняйте параметры GUI, не нажимая вручную. Скрипт должен получить доступ к классу ConstructGUITabs () для вызова событий щелчка.
Вот пример сценария тестирования, который отлично работает, если я вызываю события щелчка.
GUI .py - скрипт изменен для объявления GUIConnect как глобальных переменных с использованием 'import globfile'
from TabWidgetClass import ConstructGUITabs
import globfile
class mainWindow(QtGui.QMainWindow):
def __init__(self,**kwargs):
super().__init__()
self.dockList = []
#Lets build&run GUI
self.BuildRunGUI() ### initialize GUI
def BuildRunGUI(self):
### frame, status definition
### tab definition
self.mainWidget = QtGui.QTabWidget(self)
self.setCentralWidget(self.mainWidget)
globfile.GUIConnect = ConstructGUITabs(docklist=self.dockList, parent_widget=self.mainWidget,mutex=self.mutex)
........
Test_Script.py
import globfile
globfile.GUIConnect.get_button.click() #this invokes get_new_value
globfile.GUIConnect.set_button.click()# this set_value
Как видите здесь с помощью функции * click () мы снова выполняем события щелчка мыши. Я не хочу этого делать. Итак, я попробовал
globfile.GUIConnect.set_value()# this set_value
# This set_Value() would work as we are using only single & main thread
globfile.GUIConnect.get_new_value() #this invokes get_new_value
# This function call wont' get completed. It would stuck at 'self.read_info_flash.emit(flashData)' in BackQThread.py script. Hence, background thread fails to run update function 'update_info_from_flash'.
Кто-нибудь может сказать мне, что не так в прямом вызове функций, а не событий click (). Почему не удается выполнить только многопоточность.