Answer the question
In order to leave comments, you need to log in
Why does the GUI freeze?
I am writing a program in pyqt5 + qml.
By the button I carry out calculations and it is necessary to display the progress of the calculation.
The progress is displayed in the console perfectly, but the gui hangs for the duration of the calculation and comes to life only after execution and writes the status "done".
I tried to do calculations in one thread, and draw gui in another - the result remains unchanged
How to make the gui not hang during the calculation?
#!/usr/bin/python
import apt
import time
import threading
import mysql.connector
from PyQt5.QtGui import QGuiApplication
from PyQt5.QtCore import QObject, pyqtSignal, pyqtSlot, pyqtProperty
from PyQt5.QtQml import QQmlApplicationEngine
class Application(QObject, apt.progress.base.InstallProgress):
def __init__(self):
QObject.__init__(self)
apt.progress.base.InstallProgress.__init__(self)
self._pkg = None
self.progress = 0.
self.last = 0.0
progressResult = pyqtSignal(float, arguments=['progress'])
def start_update(self):
pass
def finish_update(self):
self.last = 100.0
self.progressResult.emit(self.last)
print self.last
print "finish"
def status_change(self, pkg, percent, status):
if percent <= 100.0:
self.last = percent
self.progressResult.emit(self.last)
print self.last
def update_interface(self):
apt.progress.base.InstallProgress.update_interface(self)
# usefull to e.g. redraw a GUI
time.sleep(0.1)
@pyqtSlot(str)
def removePackage(self, packName):
self._c = apt.Cache()
self._pkg = self._c[packName]
if self._pkg.is_installed:
self._pkg.mark_delete(True, True)
try:
threading.Thread(target=self._c.commit(install_progress=Application()), daemon=True).start()
except:
pass
self.progressResult.emit(100)
self._c.close()
def window():
import sys
# Create an instance of the application
app = QGuiApplication(sys.argv)
# Create QML engine
engine = QQmlApplicationEngine()
# Create a calculator object
application = Application()
# And register it in the context of QML
engine.rootContext().setContextProperty("application", application)
# Load the qml file into the engine
engine.load("qml/main.qml")
engine.quit.connect(app.quit)
sys.exit(app.exec_())
# Main Function
if __name__ == '__main__':
window()
Answer the question
In order to leave comments, you need to log in
Use QThread:
import sys
import time
from PyQt5 import QtCore, QtWidgets
class SlowTask(QtCore.QThread):
updated = QtCore.pyqtSignal(int)
running = False
def __init__(self, *args, **kwargs):
super(SlowTask, self).__init__(*args, **kwargs)
self.percent = 0
self.running = True
def run(self):
while self.running:
self.percent += 1
self.percent %= 100
self.updated.emit(int(self.percent))
time.sleep(0.1)
def stop(self):
self.running = False
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, *args, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
self.setupUi()
def setupUi(self):
self.setWindowTitle("Test")
self.resize(446, 207)
self.progressbar = QtWidgets.QProgressBar(self)
self.progressbar.setGeometry(QtCore.QRect(40, 70, 381, 23))
self.progressbar.setProperty("value", 0)
self.btn_start = QtWidgets.QPushButton("Start", self)
self.btn_start.setGeometry(QtCore.QRect(110, 110, 75, 23))
self.btn_start.setEnabled(True)
self.btn_start.clicked.connect(self.on_start)
self.btn_stop = QtWidgets.QPushButton("Stop", self)
self.btn_stop.setGeometry(QtCore.QRect(260, 110, 75, 23))
self.btn_stop.setEnabled(False)
self.btn_stop.clicked.connect(self.on_stop)
def toggle_buttons(self):
self.btn_start.setEnabled(not self.btn_start.isEnabled())
self.btn_stop.setEnabled(not self.btn_stop.isEnabled())
def on_update(self, data):
self.progressbar.setValue(data)
# if data == 99:
# self.on_stop()
def on_start(self):
self.toggle_buttons()
self.task = SlowTask(self)
self.task.updated.connect(self.on_update)
self.task.start()
def on_stop(self):
self.task.stop()
self.progressbar.setValue(0)
self.toggle_buttons()
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question