Hi all,
I'm heaving problems with offloading some CPU-intensive calculations to a separate thread. My GUI's response is too slow, sometimes it takes several seconds to repaint/refresh. I have a dual-core CPU with recent amd64-Linux running.
Maybe there is some misunderstanding: so far I thought it's only about starting the background thread and let it go. I have been reading Keeping the GUI responsive but it has not really help me yet. As you can see in the code (below), my thread does not do anything useful except from eating loads of CPU-cycles.
Here is what I've tried so far:
The only thing that helped me a little bit was setting the thread priority. Is there anything I can do to let my program have a better response time? I'm especially interested in solutions that work with third-party code, meaning invoking CPU-intensive methods from external libraries which I cannot extend with Qt-related functionality.
Thank you for your support in advance,
Rainer
import sys
from PySide import QtGui, QtCore, QtUiTools
# Import the compiled UI module
from customwidget import Ui_customWidget
class CCalculation
(QtCore.
QThread):
sProgress = QtCore.Signal(int)
sFinished = QtCore.Signal()
def __init__(self, pData):
super(CCalculation, self).__init__()
self.mData = pData
def run(self):
lCnt = 0
lTotal = len(self.mData)
# lLast = datetime.datetime.now()
for lNum in self.mData:
self.mData[lCnt] = lNum ** 2
# lNow = datetime.datetime.now()
# if (lNow - lLast) > datetime.timedelta(0, 0, 100000):
# lLast = lNow
# QtCore.QCoreApplication.processEvents()
if 100 * lCnt / lTotal % 10 == 0:
self.sProgress.emit(100 * lCnt / lTotal)
lCnt = 0
self.sFinished.emit()
class CMain:
sNumElements = 200000
sAccessElement = 22
def __init__(self):
# GUI code
self.mFactory = Ui_customWidget()
self.mFactory.setupUi(self.mWidget)
self.mWindow.setCentralWidget(self.mWidget)
# Threading
self.mData = range(CMain.sNumElements)
self.mThread = CCalculation(self.mData)
self.
mThreadRunning = QtCore.
QMutex()
# wire signals and slots
self.mThread.sProgress.connect(self.mFactory.progressBar.setValue)
self.mThread.sFinished.connect(self.threadFinished)
self.mFactory.processButton.clicked.connect(self.startThread)
def startThread(self):
if self.mThreadRunning.tryLock() == True:
#self.mThread.start(QtCore.QThread.IdlePriority)
self.mThread.start()
def threadFinished(self):
self.mFactory.textEdit.setText(str(self.mData[CMain.sAccessElement]))
self.mThreadRunning.unlock()
def run(self):
self.mWindow.show()
lReturn = self.mApp.exec_()
self.mThread.quit()
self.mThread.wait()
sys.exit(lReturn)
if __name__ == "__main__":
lMain = CMain()
lMain.run()
import sys
from PySide import QtGui, QtCore, QtUiTools
# Import the compiled UI module
from customwidget import Ui_customWidget
class CCalculation(QtCore.QThread):
sProgress = QtCore.Signal(int)
sFinished = QtCore.Signal()
def __init__(self, pData):
super(CCalculation, self).__init__()
self.mData = pData
def run(self):
lCnt = 0
lTotal = len(self.mData)
# lLast = datetime.datetime.now()
for lNum in self.mData:
self.mData[lCnt] = lNum ** 2
# lNow = datetime.datetime.now()
# if (lNow - lLast) > datetime.timedelta(0, 0, 100000):
# lLast = lNow
# QtCore.QCoreApplication.processEvents()
if 100 * lCnt / lTotal % 10 == 0:
self.sProgress.emit(100 * lCnt / lTotal)
lCnt = 0
self.sFinished.emit()
class CMain:
sNumElements = 200000
sAccessElement = 22
def __init__(self):
# GUI code
self.mApp = QtGui.QApplication(sys.argv)
self.mWindow = QtGui.QMainWindow()
self.mWidget = QtGui.QWidget()
self.mFactory = Ui_customWidget()
self.mFactory.setupUi(self.mWidget)
self.mWindow.setCentralWidget(self.mWidget)
# Threading
self.mData = range(CMain.sNumElements)
self.mThread = CCalculation(self.mData)
self.mThreadRunning = QtCore.QMutex()
# wire signals and slots
self.mThread.sProgress.connect(self.mFactory.progressBar.setValue)
self.mThread.sFinished.connect(self.threadFinished)
self.mFactory.processButton.clicked.connect(self.startThread)
def startThread(self):
if self.mThreadRunning.tryLock() == True:
#self.mThread.start(QtCore.QThread.IdlePriority)
self.mThread.start()
def threadFinished(self):
self.mFactory.textEdit.setText(str(self.mData[CMain.sAccessElement]))
self.mThreadRunning.unlock()
def run(self):
self.mWindow.show()
lReturn = self.mApp.exec_()
self.mThread.quit()
self.mThread.wait()
sys.exit(lReturn)
if __name__ == "__main__":
lMain = CMain()
lMain.run()
To copy to clipboard, switch view to plain text mode
Bookmarks