Solved syncing issues and application not closing upon exit of window
-
I wrote a progam that takes data from an instrument and paints graphics on the screen representing the data using qpainter. I'm using a loop that implements QApplication.processEvents() at the end and an gui.updateGraphics() fn that tells the interface when to update. the application lingers when the window is closed, so i added a conditional at the end of the loop that breaks if the esc key is hit, but the issue still persists.
if __name__ == "__main__": vars.t0 = time.clock() app = QApplication(sys.argv) gui = interfaceLab.indicators() gui.show() dev.devConnect() scope1 = vars.scope1 # scope2 = vars.scope2 dev.initLJ() dev.initScope(scope1) # dev.initScope(scope2) dev.ioConfig(scope1) # dev.ioConfig(scope2) while True: dev.acqConfig(scope1) w1 = dev.getDataCh1(scope1) scaled_wave1 = dev.scaleWave(w1,scope1) w2 = dev.getDataCh2(scope1) scaled_wave2 = dev.scaleWave(w2,scope1) w3 = dev.getDataCh3(scope1) scaled_wave3 = dev.scaleWave(w3,scope1) w4 = dev.getDataCh4(scope1) scaled_wave4 = dev.scaleWave(w4,scope1) # dev.acqConfig(scope2) # h1 = dev.getDataCh1(scope2) # scaled_waveH1 = dev.scaleWave(h1,scope2) # h2 = dev.getDataCh2(scope2) # scaled_waveH2 = dev.scaleWave(h2,scope2) tempAIN0 = dev.getDataLJAIN0() tempAIN1 = dev.getDataLJAIN1() tempAIN2 = dev.getDataLJAIN2() tempAIN3 = dev.getDataLJAIN3() vars.temp1 = tempAIN0 vars.temp2 = tempAIN1 vars.temp3 = tempAIN2 vars.temp4 = tempAIN3 vars.primP = activePowerPrim*10000 vars.secP = activePowerSec*10000 if vars.esc == True: dev.errorCheck(scope1) dev.closeAll(scope1) break
the interface file is:
class indicators(QWidget): vars.t0 = time.clock() update_grahics = False # flag for updating graphics global windowDim # global variable for window dimensions global windowPos # global variable for window dimensions screenRes = [1920,1080] # screen dimensions [x,y] windowDim = [1750,960] # window dimensions [x,y] windowPos = [(screenRes[0]-windowDim[0])/2,(screenRes[1]-windowDim[1])/2] # window position [x,y] #class initialization def __init__(self): super().__init__() self.initUI() # run initUI fn #fn to initialize UI def initUI(self): self.setGeometry(windowPos[0], windowPos[1], windowDim[0], windowDim[1]) # build screen self.setWindowTitle('Megatron') # set window title # Set window background color self.setAutoFillBackground(True) p = self.palette() p.setColor(self.backgroundRole(), Qt.black) self.setPalette(p) self.show() def keyPressEvent(self, e): if e.key() == Qt.Key_Escape: vars.esc = True self.close() #fn that triggers graphics update def updateGraphics(self): self.update_graphics = True # set update flag to true self.repaint() # repaint #fn to paint def paintEvent(self, event): qp = QPainter() # create instance of qpainter qp.begin(self) # begin painting qp.setRenderHint(QPainter.Antialiasing) # render with antialiasing self.graphics(qp) # evaluate graphics function, pass in qpainter qp.end() # end painting def graphics(self, qp): if self.update_graphics:
lots of painting here, such as this 'lcd', then:
#lcds scaleFact = 1/(self.logicalDpiX()/96) numRows = 12 numColumns = 3 rectDim = [windowDim[0]/numColumns,windowDim[1]/numRows] padding = 10 digs = 5 fontSize = int(rectDim[0]*rectDim[1]/1490) qp.setFont(QtGui.QFont("Agency FB", fontSize*scaleFact, QtGui.QFont.Bold)) qp.setPen(QPen(QColor(226, 47, 223))) gui.updateGraphics() QApplication.processEvents() # print("Active Primary Power: {} kW".format(vars.primP)) # print("Active Secondary Power: {} kW".format(vars.secP)) self.update_graphics = False # set the flag back to False sys.exit(app.exec_())
my question is, is there a better way to be controlling when this gui is updating than a loop with this flag scheme (such as eventtimer?) also: i've gotten a few thread errors in the past, do I need to implement threading? and most importantly how do I close this, some sort of closeEvent?!
-
Hi,
What about using the approach of the mandelbrot example ?
You'll render your graphic in a secondary thread and send a ready to show QImage to your GUI.
-
thank you; this example may be helpful, i will play around with it.
-
ok i don't think i actually need to add threading now (but i may at some point later), but the problem of closing the window AND the program still remains. is there a 'on window close' pyqt fn? or is there something i'm forgetting to do to close Qapplication?
-
The QWidget::closeEvent method is likely what you are looking for.
-
I never create a QWidget. I just removed app.exec_() from sys.exit(app.exec_()) leaving just sys.exit() at the end of my program, this seemed to fix it. My program is just an infinite loop that closes upon hitting the esc key or close the window through closeEvent, so do I just not need the app.exec_() argument?
-
I misread your sample code.
You should rather move that infinite loop in its own thread. What you are doing is that you are blocking the event loop so it can't process correctly.
Again, the mandlebrot example shows a nice way to do that.
-
@SGaist thanks for your help!
-
You're welcome !
Since you have it working now, please mark the thread as solved using the "Topic Tools" button so that other forum users may know a solution has been found :)