GiUnZ | 2021-06-27 18:56:12 UTC | #1
I am trying to create an application that will be getting data through an API and present them in QTreeView, using PySide6. As it takes a long time to get the data I want to retrieve them using a QThread. My example code is the following: import logging import time
from PySide6.QtCore import *
from PySide6.QtGui import *
from PySide6.QtWidgets import *
logging.basicConfig(
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
level=logging.INFO)
class MainWindow(QMainWindow):
gettingData = False
counting = False
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.counter = 0
layout = QVBoxLayout()
self.b = QPushButton("Start Counting with a Thread")
self.bt1 = QPushButton("Generate tree with Thread")
self.bt2 = QPushButton("Generate tree without a Thread")
self.tree = QTreeView()
layout.addWidget(self.b)
layout.addWidget(self.bt1)
layout.addWidget(self.bt2)
layout.addWidget(self.tree)
self.b.clicked.connect(self.startCounting)
self.bt1.clicked.connect(self.startGenerating)
self.bt2.clicked.connect(self.startGenerating2)
w = QWidget()
w.setLayout(layout)
self.setCentralWidget(w)
self.show()
self.threadpool = QThreadPool()
print("Multithreading with maximum %d threads" % self.threadpool.maxThreadCount())
def startCounting(self):
thread = Thread(self.counting)
thread.signal.signal.connect(self.something)
self.threadpool.start(thread)
def something(self, signal):
if signal == "False":
logging.info("Counting is Complete")
else:
logging.info(signal)
def startGenerating(self):
thread = DataThread()
thread.signals.signal_QStandardItemModel(self.treeAction)
self.threadpool.start(thread)
def treeAction(self,signal):
self.tree.setModel(signal)
def startGenerating2(self):
start = time.perf_counter()
siteTreeViewModel = QStandardItemModel()
rootNode = siteTreeViewModel.invisibleRootItem()
aItem = TreeStandardItem("A")
bItem = TreeStandardItem("B")
cItem = TreeStandardItem("C")
rootNode.appendRow(aItem)
time.sleep(3)
rootNode.appendRow(bItem)
time.sleep(3)
bItem.appendRow(cItem)
self.tree.setModel(siteTreeViewModel)
end = time.perf_counter() - start
logging.info("Generated tree in "+str(end))
class Thread(QRunnable):
def __init__(self, counting):
super().__init__()
self.counting = counting
self.signal = Signal()
def run(self):
for x in range(10):
self.signal.signal.emit(str(x))
time.sleep(.1)
counting = False
self.signal.signal.emit(str(counting))
class Signal(QObject):
signal = Signal(str)
class DataThread(QRunnable):
def __init__(self):
super().__init__()
self.signals = WorkerSignals()
def run(self):
logging.info("Start generating the tree")
start = time.perf_counter()
siteTreeViewModel = QStandardItemModel()
rootNode = siteTreeViewModel.invisibleRootItem()
aItem = TreeStandardItem("A")
bItem = TreeStandardItem("B")
cItem = TreeStandardItem("C")
rootNode.appendRow(aItem)
time.sleep(2)
rootNode.appendRow(bItem)
time.sleep(2)
bItem.appendRow(cItem)
end = time.perf_counter() - start
self.signals.signal_QStandardItemModel.emit(siteTreeViewModel)
logging.info("Generated tree in "+str(end))
self.signals.finished.emit()
class TreeStandardItem(QStandardItem):
def __init__(self, txt=''):
super().__init__()
self.setEditable = False
self.setForeground(QColor(255, 255, 255))
self.setText(txt)
class WorkerSignals(QObject):
signal_QStandardItemModel = Signal()
finished = Signal()
app = QApplication([])
window = MainWindow()
app.exec()
The first counting button works as expected creating a thread. Generating the tree without a thread, confirms that the code I am trying to run using a thread is working Once I try running the tree generation using thread, I get the following error:
Traceback (most recent call last):
File "/home/giunz/code/tutorial/threaded-tree-01.py", line 61, in startGenerating
thread.signals.signal_QStandardItemModel(self.treeAction)
TypeError: 'Signal' object is not callable
Any help on how to generate the tree using a thread, would be appreciated.
Thanks in advance