Can't invoke button click function() outside pyQT based GUI

ε祈祈猫儿з 提交于 2020-06-09 06:37:48

问题


I am trying to enhance the existing pyQT based GUI framework. The GUI is a multithread GUI based out of pyQT. I have taken some portion of it here to explain the problem

GUI.py - main python script that invokes function to create Tab on 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 - Script to create tabs & widgets

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)

The 2 library modules SerialInterface & BackQThread are as below:

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

All above interface works without issues.

The new requirement is to do automation on GUI. In such way that, execute GUI options without manually doing clicks. Script should get an access to ConstructGUITabs() class, to invoke the click events.

Here is sample test script which works fine, if I invoke click events.

GUI.py - script is modified to declare GUIConnect as global variables using '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

As you see here, through *click() function we are again doing mouse click events. I dont want to do this. So i tried

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'. 

Can anyone tell me, what is the wrong in invoking directly functions rather than click() events. Why multithread alone fails to complete.

来源:https://stackoverflow.com/questions/62083406/cant-invoke-button-click-function-outside-pyqt-based-gui

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!