0

I want to use startup function which should have while loop. but I run the code my gui doesn't appear until while loop ends.

I tried with self.show() it can make show gui but it doesn't allow to use sys.exit()

import sys
from PyQt5.QtWidgets import QApplication
from PyQt5 import uic
import time

form_class,QMainWindow=uic.loadUiType('youhua.ui')

class MyWindow(QMainWindow,form_class):

    def __init__(self):
        super().__init__()
        self.setupUi(self)
        #self.show()
        self.myfunc()

    def myfunc(self):

        k=1
        stat=True
        while stat:
            k=k+1
            time.sleep(1)
            self.statusMessage.append(str(k))
            QApplication.processEvents()
            if k>10:
                stat=False
                #sys.exit()


if __name__=='__main__':
    app=QApplication(sys.argv)
    myWindow=MyWindow()
    myWindow.show()
    app.exec_()

2 Answers 2

1

If you need to perform an action again, you have several options. For example, if each iteration takes very little time, without the possibility of blocking the main loop, you can replace the cycle with a timer (QTimer) and call the method each time, which is responsible for obtaining new data and updating the necessary interface elements in accordance with them:

import sys
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtWidgets import QApplication, QMainWindow
from PyQt5 import uic
from PyQt5.QtCore import QThread, QTimer
import time

#form_class, QMainWindow = uic.loadUiType('youhua.ui')

class MyWindow(QMainWindow): #, form_class):
    def __init__(self):
        super().__init__() 
        self.k = 0

        centralWidget = QtWidgets.QWidget(self)
        self.setCentralWidget(centralWidget)        

        self.button = QtWidgets.QPushButton('Start', self)
        self.button.clicked.connect(self.read_data)

        self.label_data = QtWidgets.QLabel(self, alignment=QtCore.Qt.AlignCenter)
        self.label_data.setText('Pending')

        layout = QtWidgets.QGridLayout(centralWidget)        
        layout.addWidget(self.label_data)
        layout.addWidget(self.button)

        self.timer = QtCore.QTimer(self)
        self.timer.setInterval(1000)                             
        self.timer.timeout.connect(self.read_data_from_sensor)

    @QtCore.pyqtSlot()
    def read_data(self):
        ''' Start / Stop reading at the touch of a button '''

        if not self.timer.isActive():
            self.timer.start()
            self.button.setText("Stop")
        else:
            self.timer.stop()
            self.button.setText("Start")
            self.label_data.setText("Pending")

    @QtCore.pyqtSlot()
    def read_data_from_sensor(self):
        dt  = time.strftime("%Y-%m-%d %H:%M:%S")
        self.label_data.setText(dt)
        self.label_data.adjustSize()

        self.k += 1
        self.statusBar().showMessage('{} item(s)'.format(self.k))

        if self.k > 10:        
            self.timer.stop()
            self.button.setText("Start")
            self.label_data.setText("Pending")        
            self.k = 0

if __name__=='__main__':
    app = QApplication(sys.argv)
    myWindow = MyWindow()
    myWindow.show()
    app.exec_()

enter image description here


What you wrote may also work, but this is not very good. You can compare.

import sys
from PyQt5.QtWidgets import QApplication, QMainWindow
from PyQt5 import uic
from PyQt5.QtCore import QThread
#import time

#form_class, QMainWindow = uic.loadUiType('youhua.ui')

class MyWindow(QMainWindow): #, form_class):

    def __init__(self):
        super().__init__() 
#        self.setupUi(self)

        self.show()            
        self.myfunc()

    def myfunc(self):
        k = 0
        stat = True
        while stat:
            k += 1
#            time.sleep(1)
#            self.statusMessage.append(str(k))

            self.statusBar().showMessage('{} item(s)'.format(k))
            QThread.msleep(1000)
            QApplication.processEvents()

            if k>10:
                stat=False
                #sys.exit()


if __name__=='__main__':
    app = QApplication(sys.argv)
    myWindow = MyWindow()
#    myWindow.show()
    app.exec_()
Sign up to request clarification or add additional context in comments.

Comments

0

In your loop you are sleeping for 10 second, since you are creating a while loop on the main thread, the GUI wont show until the loop is done because it would be blocking the main thread. You can test this by removing time.sleep(1).

Without changing your code much, try this:

import sys,threading, time
from PyQt5.QtWidgets import QApplication
from PyQt5 import uic

form_class,QMainWindow=uic.loadUiType('youhua.ui')

class MyWindow(QMainWindow,form_class):

    def __init__(self):
        super().__init__()
        self.setupUi(self)
        #self.show()
        t = threading.Thread(target=self.myfunc)
        t.start()

    def myfunc(self):
        k=1
        stat=True
        while stat:
            k=k+1
            time.sleep(1)
            self.statusMessage.append(str(k))
            QApplication.processEvents()
            if k>10:
                stat=False
                #sys.exit() - if you are trying to close the window here use self.close()


if __name__=='__main__':
    app=QApplication(sys.argv)
    myWindow=MyWindow()
    myWindow.show()
    sys.exit(app.exec_())

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.