Sure, see the end of this message (only 58 lines, so I figured inline was probably fine). It’s not *quite* as extreme an effect as what I am seeing in my application (probably due to over-simplification), but it still illustrates the problem: click the button, and try typing quickly in the the line edit. While the thread is running, typing speed is noticeably reduced over when the thread is not running. The thread apparently doesn’t *completely* block the GUI (I’m not sure why - maybe the GIL is released between loop iterations?), but it does introduce noticeable lags. It’s those lags I’m trying to get rid of. Simplified example: import time from PySide2.QtWidgets import (QApplication, QMainWindow, QPushButton, QLineEdit, QVBoxLayout, QWidget) from PySide2.QtCore import (QThread) class LongRunningThread(QThread): """A process that takes several seconds to complete, involving manipulation of data contained in large data structures that are members of the MainWindow instance.""" def __init__(self, dataset): super().__init__() self.dataset = dataset def run(self): print("Thread running") start_time = time.time() for idx, val in enumerate(self.dataset): self.dataset[idx] = val * 50 print(f"Thread complete after: {time.time()-start_time}") class MainWindow(QMainWindow): """Main application class, contains large data structures that can not/should not be easily copied to another process for various reasons such as memory usage.""" def __init__(self): super().__init__() central_widget = QWidget(self) layout = QVBoxLayout() central_widget.setLayout(layout) self.setCentralWidget(central_widget) self.text_entry = QLineEdit(self) layout.addWidget(self.text_entry) self.button = QPushButton("Run Thread") self.button.clicked.connect(self._run_blocking_thread) layout.addWidget(self.button) # Generate a random dataset. Adjust size so operations take a while. self.large_dataset = list(range(20000000)) def _run_blocking_thread(self): self.thread = LongRunningThread(self.large_dataset) self.thread.start() print("Thread started!") if __name__ == "__main__": app = QApplication() win = MainWindow() win.show() app.exec_() |
import time from PySide2.QtWidgets import (QApplication, QMainWindow, QPushButton, QLineEdit, QVBoxLayout, QWidget)
from PySide2.QtCore import (QThread) class LongRunningThread(QThread): """A process that takes several seconds to complete, involving manipulation of data contained in large data structures that are members of the MainWindow instance.""" def __init__(self, dataset): super().__init__() self.dataset = dataset def run(self): print("Thread running") start_time = time.time() for idx, val in enumerate(self.dataset): self.dataset[idx] = val * 50 print(f"Thread complete after: {time.time()-start_time}") class MainWindow(QMainWindow): """Main application class, contains large data structures that can not/should not be easily copied to another process for various reasons such as memory usage.""" def __init__(self): super().__init__() central_widget = QWidget(self) layout = QVBoxLayout() central_widget.setLayout(layout) self.setCentralWidget(central_widget) self.text_entry = QLineEdit(self) layout.addWidget(self.text_entry) self.button = QPushButton("Run Thread") self.button.clicked.connect(self._run_blocking_thread) layout.addWidget(self.button) # Generate a random dataset. Adjust size so operations take a while. self.large_dataset = list(range(20000000)) def _run_blocking_thread(self): self.thread = LongRunningThread(self.large_dataset) self.thread.start() print("Thread started!") if __name__ == "__main__": app = QApplication() win = MainWindow() win.show() app.exec_()
--- Israel Brewster Software Engineer Alaska Volcano Observatory Geophysical Institute - UAF 2156 Koyukuk Drive Fairbanks AK 99775-7320 Work: 907-474-5172 cell: 907-328-9145
|
_______________________________________________ PySide mailing list PySide@qt-project.org https://lists.qt-project.org/listinfo/pyside