I know this might be repeating the same question that someone else asked already, but I still don't understand what is happening actually. I have seen a lot of examples for multithreading in this forum and have compiled a dummy demo of what my actual application going to do. Here is the code:
import sys
from PySide2.QtCore import *
from PySide2.QtWidgets import *
from PySide2.QtGui import *
class Color(QWidget):
def __init__(self, color):
super(Color, self).__init__()
self.setAutoFillBackground(True)
palette = self.palette()
palette.setColor(QPalette.Window, QColor(color))
self.setPalette(palette)
class Inlet_Thread(QThread):
data = Signal(int)
tabs = Signal(int)
finish = Signal()
def __init__(self):
super().__init__()
self._stopped = False
self.init_timers()
print('new thread')
self.c = 0
self.d = 0
def init_timers(self):
self.timer1 = QTimer(self)
self.timer1.timeout.connect(self.routine)
self.timer2 = QTimer(self)
self.timer2.timeout.connect(self.routine2)
def starter(self):
self.timer1.start(1000)
self.timer2.start(2000)
def run(self):
while not self._stopped:
pass
self.timer1.stop()
self.timer2.stop()
print('stopped')
self.finish.emit()
def routine(self):
self.data.emit(self.c)
self.c += 1
def routine2(self):
self.tabs.emit(self.d)
self.d += 1
#Slot()
def stop(self):
self._stopped = True
class Inlet_Worker(QObject):
data = Signal(int)
tabs = Signal(int)
def __init__(self):
super().__init__()
self._stopped = False
self._registered = False
self.init_timers()
self.c = 0
self.d = 0
def init_timers(self):
self.timer1 = QTimer(self)
self.timer1.timeout.connect(self.routine)
self.timer2 = QTimer(self)
self.timer2.timeout.connect(self.routine2)
def starter(self):
self.timer1.start(1000)
self.timer2.start(2000)
def routine(self):
self.data.emit(self.c)
self.c += 1
def routine2(self):
self.tabs.emit(self.d)
self.d += 1
#Slot()
def stop(self):
self.timer1.stop()
self.timer2.stop()
print('stopped')
class Window(QWidget):
startSig = Signal()
stopSig = Signal()
def __init__(self):
super().__init__()
self.dlg = Dialog()
self.thread = None
pagelayout = QVBoxLayout(self)
button_layout = QHBoxLayout()
self.stacklayout = QStackedLayout()
pagelayout.addLayout(button_layout)
pagelayout.addLayout(self.stacklayout)
self.button = QPushButton('Start')
self.button2 = QPushButton('Stop')
self.button3 = QPushButton('Window')
button_layout.addWidget(self.button)
button_layout.addWidget(self.button2)
button_layout.addWidget(self.button3)
self.stacklayout.addWidget(Color("red"))
self.stacklayout.addWidget(Color("yellow"))
self.stacklayout.addWidget(Color("green"))
self.button.clicked.connect(self.startThr2)
self.button2.clicked.connect(self.stopThr)
self.button3.clicked.connect(self.showDlg)
#Slot(int)
def switch_tab(self, d):
idx = d % 3
print(idx)
self.stacklayout.setCurrentIndex(idx)
def showDlg(self):
if not self.dlg.isVisible():
self.dlg.show()
def startThr(self):
self.thread = QThread()
self.worker = Inlet_Worker()
self.worker.moveToThread(self.thread)
self.worker.data.connect(self.dlg.update)
self.worker.tabs.connect(self.switch_tab)
self.stopSig.connect(self.worker.stop)
self.thread.started.connect(self.worker.starter)
self.thread.start()
def startThr2(self):
if self.thread is None or not self.thread.isRunning():
self.thread = Inlet_Thread()
self.thread.started.connect(self.thread.starter)
self.thread.data.connect(self.dlg.update)
self.thread.tabs.connect(self.switch_tab)
self.thread.finish.connect(self.finished)
self.stopSig.connect(self.thread.stop)
self.thread.start()
def stopThr(self):
self.stopSig.emit()
def finished(self):
print('thread finished')
self.thread.quit()
self.thread.wait()
def closeEvent(self, event):
#self.stopThr()
pass
class Dialog(QWidget):
def __init__(self):
super().__init__()
self.text1 = QLabel("Label 1 : ")
self.text2 = QLabel("Text2")
layout = QHBoxLayout(self)
layout.addWidget(self.text1)
layout.addWidget(self.text2)
self.setGeometry(400, 100, 100, 50)
#Slot(int)
def update(self, sig):
self.text2.setText(str(sig))
def closeEvent(self, event):
pass
if __name__ == '__main__':
app = QApplication(sys.argv)
window = Window()
window.setGeometry(750, 80, 300, 80)
window.show()
sys.exit(app.exec_())
While the threading is performing fine, it returns an error:
QObject::killTimer: Timers cannot be stopped from another thread
And if I use the Qobject and move it to a thread, an additional error appears
QObject::~QObject: Timers cannot be stopped from another thread
Can someone explain what is causing the error?
EDIT:
I changed the code to be more complex and show where each data will go. The reason I'm using Qtimer in a thread is that there are multiple signals to emit and the frequency and shape of each data is different. Since this code is only a simplification of my actual application, there might be some different parts. And if there are alternatives, I'm open to suggestions.
Related
I want to turn the dial on pyqt's GUI to change parameters while sounddevice's outputstream is processing, but the GUI freezes. I've tried everything I could find, and I've pieced together a bunch of code, but I'd like to know what the solution is.
I want to change the equalizer of the music being played in near real time by changing the parameters of the pedalboard that grants the equalizer.
import sys
import time
from PyQt5.QtCore import QObject, QThread, pyqtSignal
from PyQt5.QtWidgets import *
from PyQt5.QtMultimedia import QSound
from pedalboard import *
import sounddevice as sd
import librosa
from threading import *
import threading
import soundfile as sf
def long_running_function(update_ui,board):
event = threading.Event()
try:
data, fs = sf.read('continue.wav', always_2d=True)
current_frame = 0
def callback(outdata, frames, time, status):
nonlocal current_frame
if status:
print(status)
chunksize = 2024
#print(chunksize, current_frame,len(data),frames)
outdata[:chunksize] = board(data[current_frame:current_frame + chunksize])
if chunksize < 2024:
outdata[chunksize:] = 0
raise sd.CallbackStop()
current_frame += chunksize
stream = sd.OutputStream(
samplerate=fs, blocksize=2024 , channels=data.shape[1],
callback=callback, finished_callback=event.set)
with stream:
event.wait()
except KeyboardInterrupt:
exit('\nInterrupted by user')
class Worker(QObject):
finished = pyqtSignal()
progress = pyqtSignal(int)
def __init__(self, main_window):
self.main_window = main_window
super(Worker, self).__init__(main_window)
def run(self):
long_running_function(self.update_progress,self.main_window.make_board())
self.finished.emit()
def update_progress(self, percent):
self.progress.emit(percent)
class MainWindow(QMainWindow):
def __init__(self):
super(self.__class__, self).__init__()
self.progress = QProgressBar()
self.button = QPushButton("Start")
self.dial = QDial()
self.init_ui()
self.qsound = None
self.qsound2 = None
self.effected_audio = None
self.audio = None
self.sr = None
self.dial.valueChanged.connect(self.make_board)
self.button.clicked.connect(self.execute)
self.show()
def init_ui(self):
self.setGeometry(100, 100, 250, 250)
layout = QVBoxLayout()
layout.addWidget(self.progress)
layout.addWidget(self.button)
layout.addWidget(self.dial)
self.setWindowTitle('Audio Player')
button_play = QPushButton("環境音を再生")
button_play2 = QPushButton("音楽と環境音を再生")
button_stop = QPushButton("Stop")
button_dialog = QPushButton("音楽を選択")
button_dialog2 = QPushButton("環境音を選択")
dial = QDial()
live = QPushButton("LIVE")
self.label = QLabel(self)
self.label2 = QLabel(self)
layout.addWidget(button_dialog)
layout.addWidget(button_dialog2)
layout.addWidget(button_play)
layout.addWidget(button_stop)
layout.addWidget(button_play2)
layout.addWidget(live)
layout.addWidget(self.dial)
layout.addWidget(self.label)
layout.addWidget(self.label2)
button_dialog.clicked.connect(self.button_openfile)
button_dialog2.clicked.connect(self.button_openfile2)
button_play.clicked.connect(self.button_play)
button_play2.clicked.connect(self.button_play2)
button_stop.clicked.connect(self.button_stop)
live.clicked.connect(self.start)
self.dial.valueChanged.connect(self.sliderMoved)
self.dial.valueChanged.connect(self.make_board)
self.dial.setMinimum(0)
self.dial.setMaximum(20)
self.dial.setValue(5)
w = QWidget()
w.setLayout(layout)
self.setCentralWidget(w)
def sliderMoved(self):
number = self.dial.value()
print(number)
return number
def make_board(self):
board = Pedalboard([
Compressor(ratio=10, threshold_db=-20),
Gain(gain_db=self.dial.value()),
Phaser(),
Reverb()
],sample_rate=44100)
return board
def button_play(self):
print("")
def button_play2(self):
if self.qsound is not None:
board = self.make_board(self.effects)
self.effected_audio = board(self.audio,self.sr)
sd.play(self.effected_audio)
self.qsound2.play()
def button_stop(self):
if self.qsound is not None:
sd.stop()
self.qsound2.stop()
def button_openfile(self):
filepath, _ = QFileDialog.getOpenFileName(self, 'Open file','c:\\',"Audio files (*.wav)")
filepath = os.path.abspath(filepath)
self.qsound = QSound(filepath)
self.filename = os.path.basename(filepath)
self.audio, self.sr = librosa.load(self.filename, sr=44100)
self.label.setText(self.filename)
self.label.adjustSize()
def button_openfile2(self):
filepath2, _ = QFileDialog.getOpenFileName(self, 'Open file','c:\\',"Audio files (*.wav)")
filepath2 = os.path.abspath(filepath2)
self.qsound2 = QSound(filepath2)
self.filename2 = os.path.basename(filepath2)
self.label2.setText(self.filename2)
self.label2.adjustSize()
def start(self):
self.thread.start()
def execute(self):
self.update_progress(0)
self.thread = QThread()
self.worker = Worker(self)
self.worker.moveToThread(self.thread)
self.thread.started.connect(self.worker.run)
self.worker.finished.connect(self.thread.quit)
self.worker.finished.connect(self.worker.deleteLater)
self.thread.finished.connect(self.thread.deleteLater)
self.worker.progress.connect(self.update_progress)
self.thread.start()
self.button.setEnabled(False)
def update_progress(self, progress):
self.progress.setValue(progress)
self.button.setEnabled(progress == 100)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
app.exec_()
Qt Docs for moveToThread() say:
Changes the thread affinity for this
object and its children. The object
cannot be moved if it has a parent.
I cannot see where Worker instance gets started. Maybe you wanted to derive Worker from QThread, and call self.worker.start()?
OutputStream and the Qt GUI both have their own internal main loops which are responsible for handling their respective events. When you execute both on the same thread, one or the other might freeze.
This is a basic progress bar.
i just tried this code. the progress bar is loading but not stopping when i push the stop button it just contiues.
and whenever i push the stop button the application is locking until progress bar finish.
import sys
import time
from PyQt5.QtWidgets import (QApplication, QDialog,
QProgressBar, QPushButton)
TIME_LIMIT = 100
class Actions(QDialog):
"""
Simple dialog that consists of a Progress Bar and a Button.
Clicking on the button results in the start of a timer and
updates the progress bar.
"""
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.setWindowTitle('Progress Bar')
self.progress = QProgressBar(self)
self.progress.setGeometry(0, 0, 300, 100)
self.progress.setMaximum(100)
self.button = QPushButton('Start', self)
self.button.move(0, 30)
self.button2 = QPushButton('Stop', self)
self.button2.move(30, 60)
self.show()
self.show()
self.button.clicked.connect(self.onButtonClick)
self.button2.clicked.connect(self.onButtonClick2)
def onButtonClick(self):
count = 0
while count < TIME_LIMIT:
count += 1
time.sleep(1)
self.progress.setValue(count)
print(count)
stop = 0
if stop == 1:
break
def onButtonClick2(self):
stop = 1
if __name__ == "__main__":
app = QApplication(sys.argv)
window = Actions()
sys.exit(app.exec_())
In your example, the stop variable in the onButtonClick() method
and the stop variable in the onButtonClick2() method are different local variables.
The while loops and the sleep(1) function block the main interface.
The above task may look something like this:
import sys
from PyQt5.QtWidgets import (QApplication, QDialog, QProgressBar, QPushButton)
from PyQt5.QtCore import QThread, pyqtSignal
class Thread(QThread):
update_signal = pyqtSignal(int)
def __init__(self, *args, **kwargs):
super(Thread, self).__init__(*args, **kwargs)
self.count = 0
self.running = True
def run(self):
while self.running and self.count < 100:
self.count += 1
self.update_signal.emit(self.count)
QThread.msleep(100)
def stop(self):
self.running = False
class Actions(QDialog):
"""
Simple dialog that consists of a Progress Bar and a Button.
Clicking on the button results in the start of a timer and
updates the progress bar.
"""
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.setWindowTitle('Progress Bar')
self.progress = QProgressBar(self)
self.progress.setGeometry(0, 0, 300, 100)
self.progress.setMaximum(100)
self.progress.setValue(0)
self.button = QPushButton('Start', self)
self.button.move(0, 30)
self.button2 = QPushButton('Stop', self)
self.button2.setEnabled(False)
self.button2.move(30, 60)
self.button.clicked.connect(self.onButtonClick)
self.button2.clicked.connect(self.on_stop)
self.thread = Thread()
self.thread.update_signal.connect(self.update)
def onButtonClick(self):
self.button2.setEnabled(True)
self.progress.setValue(0)
self.thread.running = True
self.thread.count = 0
self.thread.start()
self.button.setEnabled(False)
def update(self, val):
self.progress.setValue(val)
if val == 100: self.on_stop()
def on_stop(self):
self.thread.stop()
self.button.setEnabled(True)
self.button2.setEnabled(False)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = Actions()
window.show()
sys.exit(app.exec_())
how to update listwidget on each iteration ?
it update listwidget after 500 iterations.
pyqt4, python3.7
def input_val(self):
for i in range(500):
time.sleep(1)
self.listWidget.addItem(str(i))
print(i)
You should not use sleep() in the main thread since it blocks the GUI eventloop, if you want to do periodic tasks then you should use a QTImer.
Based on the above the solution is:
from PyQt4 import QtCore, QtGui
class Timer(QtCore.QObject):
timeout = QtCore.pyqtSignal(int)
finished = QtCore.pyqtSignal()
def __init__(self, parent=None, **kwargs):
self._maximum = kwargs.pop("maximum", 0)
_interval = kwargs.pop("interval", 0)
_timeout = kwargs.pop("timeout", None)
_finished = kwargs.pop("finished", None)
if parent is not None:
kwargs["parent"] = parent
super(Timer, self).__init__(**kwargs)
self._counter = 0
self._timer = QtCore.QTimer(timeout=self._on_timeout)
self.interval = _interval
if _timeout:
self.timeout.connect(_timeout)
if _finished:
self.timeout.connect(_finished)
#QtCore.pyqtSlot()
def start(self):
self._timer.start()
#property
def interval(self):
return self._timer.interval()
#interval.setter
def interval(self, v):
self._timer.setInterval(v)
#property
def maximum(self):
return self._maximum
#maximum.setter
def maximum(self, v):
self._maximum = v
#QtCore.pyqtSlot()
def _on_timeout(self):
self.timeout.emit(self._counter)
self._counter += 1
if self._counter >= self.maximum:
self.finished.emit()
self._timer.stop()
class MainWindow(QtGui.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.m_listwidget = QtGui.QListWidget()
self.setCentralWidget(self.m_listwidget)
t = Timer(self, maximum=500, interval=1000, timeout=self.onTimeout)
t.start()
#QtCore.pyqtSlot(int)
def onTimeout(self, i):
self.m_listwidget.addItem(str(i))
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())
I have pyqt interface which starts a QThread if a push button is pressed. The thread run and when it's finished I can start it again, no problems up to here.
I now added a check box for continuous operation of the thread. If checkbox is checked the pushbutton remains pressed and one has to push again the button to stop the thread.
Apparently after stopping, the thread is properly finished (checked also with isRunning() method) but if I try to start it again in continuous operation the program will crash. This doesn't happen if I instead restart it with continuous operation off, but the thread is started and stopped twice in this case.
How to explain such behavior? Is there a way to make it work as intended?
An example:
import sys
from PyQt5 import QtCore
import PyQt5.QtWidgets as QtW
from PyQt5.QtCore import QThread, pyqtSlot, pyqtSignal
import time
class MyWindow(QtW.QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle('MyWindow')
self._main = QtW.QWidget()
self.setCentralWidget(self._main)
self.button = QtW.QPushButton('Do it', self)
self.button.clicked.connect(self.do)
self.contincheck = QtW.QCheckBox("Continuous")
self.contincheck.clicked.connect(self.continuous_doing)
self.continuous = False
self.layout = QtW.QGridLayout(self._main)
self.layout.addWidget(self.button,0,0)
self.layout.addWidget(self.contincheck,1,0)
self.setLayout(self.layout)
self.show()
def continuous_doing(self):
if self.contincheck.isChecked():
self.button.setCheckable(True)
self.continuous = True
else:
self.button.setCheckable(False)
self.continuous = False
def do(self):
if self.button.isCheckable() and not self.button.isChecked():
self.button.setText('Do it')
self.button.clicked.connect(self.do)
self.contincheck.setEnabled(True)
else:
self.mythread = MyThread(self.continuous)
if self.button.isCheckable() and self.button.isChecked():
self.button.setText('Stop doing that')
self.contincheck.setDisabled(True)
self.button.clicked.connect(self.mythread.stop)
self.mythread.finished.connect(self.thread_finished)
self.mythread.signal.connect(self.done)
self.mythread.start()
#pyqtSlot(int)
def done(self, i):
print('done it', i)
#pyqtSlot()
def thread_finished(self):
print('thread finished')
class MyThread(QThread):
signal = pyqtSignal(int)
def __init__(self, continuous):
QThread.__init__(self)
self._stopped = True
self.continuous = continuous
self.i = 0
def __del__(self):
self.wait()
def stop(self):
self._stopped = True
def run(self):
self._stopped = False
while True:
self.signal.emit(self.i)
if self._stopped:
break
if self.continuous: time.sleep(2)
else: break
if __name__ == '__main__':
app = QtCore.QCoreApplication.instance()
if app is None:
app = QtW.QApplication(sys.argv)
mainGui = MyWindow()
mainGui.show()
app.aboutToQuit.connect(app.deleteLater)
app.exec_()
The problem is that you are creating a new thread instead of reusing the existing one, in the following example I show you how to do it correctly:
import sys
from PyQt5 import QtCore, QtWidgets
class MyWindow(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle('MyWindow')
self._main = QtWidgets.QWidget()
self.setCentralWidget(self._main)
self.button = QtWidgets.QPushButton('Do it')
self.button.clicked.connect(self.do)
self.contincheck = QtWidgets.QCheckBox("Continuous")
self.contincheck.clicked.connect(self.continuous_doing)
self.continuous = False
layout = QtWidgets.QGridLayout(self._main)
layout.addWidget(self.button, 0, 0)
layout.addWidget(self.contincheck, 1, 0)
self.mythread = MyThread(self.continuous, self)
self.mythread.finished.connect(self.thread_finished)
self.button.clicked.connect(self.mythread.stop)
self.mythread.signal.connect(self.done)
def continuous_doing(self):
self.button.setCheckable(self.contincheck.isChecked())
self.continuous = self.contincheck.isChecked()
def do(self):
if self.button.isCheckable() and not self.button.isChecked():
self.button.setText('Do it')
self.contincheck.setEnabled(True)
else:
self.mythread.continuous = self.continuous
if self.button.isCheckable() and self.button.isChecked():
self.button.setText('Stop doing that')
self.contincheck.setDisabled(True)
self.mythread.start()
#QtCore.pyqtSlot(int)
def done(self, i):
print('done it', i)
#QtCore.pyqtSlot()
def thread_finished(self):
print('thread finished')
class MyThread(QtCore.QThread):
signal = QtCore.pyqtSignal(int)
def __init__(self, continuous=False, parent=None):
super(MyThread, self).__init__(parent)
self._stopped = True
self.continuous = continuous
self.i = 0
def __del__(self):
self.wait()
def stop(self):
self._stopped = True
def run(self):
self._stopped = False
while True:
self.signal.emit(self.i)
if self._stopped:
break
if self.continuous:
QtCore.QThread.sleep(2)
else:
break
if __name__ == '__main__':
app = QtCore.QCoreApplication.instance()
if app is None:
app = QtWidgets.QApplication(sys.argv)
mainGui = MyWindow()
mainGui.show()
app.aboutToQuit.connect(app.deleteLater)
app.exec_()
Attempting to write a class that will show the progress of a threaded process. I need to use this class for all "file load" operations; however I am having trouble making it global.
fileloader.py:
from PyQt5.QtCore import pyqtSlot, pyqtSignal
from PyQt5.QtWidgets import QDialog
from PyQt5.uic import loadUi
class FileLoader(QDialog):
completeSig = pyqtSignal()
def __init__(self, parent=None):
super(FileLoader, self).__init__(parent)
self.filename = ""
self.clientcode = ""
self.thread = ""
loadUi("GlobalUI/fileloader.ui", self)
self.prgLoader.setValue(0)
#pyqtSlot()
def on_btnCancel_clicked(self):
self.close()
def closeEvent(self, e):
self.thread.stop()
def loadData(self):
self.thread.totalSig.connect(self.prgLoader.setMaximum)
self.thread.countSig.connect(self.prgLoader.setValue)
self.thread.finished.connect(self.completed)
self.thread.start()
def completed(self):
self.completeSig.emit()
self.close()
loader.py
from PyQt5.QtCore import pyqtSignal, QThread
from fileloader import FileLoader
class DataLoader(QThread):
totalSig = pyqtSignal(int)
countSig = pyqtSignal(int)
def __init__(self, parent=None):
super(DataLoader, self).__init__(parent)
self.threadactive = True
self.commitsize = 300
self.rowdata = []
def run(self):
print("Code Will Go Here For Loading the File")
def stop(self):
self.threadactive = False
self.wait()
class PatDataLoader():
def load(self, clientcode, filename):
fl = FileLoader()
fl.clientcode = clientcode
fl.filename = filename
fl.thread = DataLoader()
fl.loadData()
I am calling PatDataLoader.load("test","test.txt") from another module. The problem I am running into is the application crashes with QThread: Destroyed while thread is still running as there seems to be a problem with the thread process I am passing to the fileloader. Am I not putting these pieces together properly?
main.py:
from lmdb.patloader import PatDataLoader
class PPSReportsApp(QMainWindow):
def __init__(self, *args):
super(PPSReportsApp, self).__init__(*args)
loadUi("GlobalUI/ppsreportswindow.ui", self)
#self.showMaximized()
#pyqtSlot()
def on_actionTest_triggered(self):
pl = PatDataLoader()
pl.load("TEST","testfile.txt")
In your code pl is a local variable so it will be deleted when it finishes executing on_actionTest_triggered which is an instant possibly generating that problem. On the other hand, no load should be a static method because it does not use the self. self.thread must be None, it is better than ""
How can you prevent pl from being deleted before it is finished processing?
fl is a QDialog so you can use exec_().
fileloader.py
class FileLoader(QDialog):
completeSig = pyqtSignal()
def __init__(self, parent=None):
super(FileLoader, self).__init__(parent)
self.filename = ""
self.clientcode = ""
self.thread = None
loadUi("GlobalUI/fileloader.ui", self)
self.prgLoader.setValue(0)
#pyqtSlot()
def on_btnCancel_clicked(self):
self.close()
def closeEvent(self, e):
if self.thread:
self.thread.stop()
def loadData(self):
if self.thread:
self.thread.totalSig.connect(self.prgLoader.setMaximum)
self.thread.countSig.connect(self.prgLoader.setValue)
self.thread.finished.connect(self.completed)
self.thread.start()
def completed(self):
self.completeSig.emit()
self.close()
loader.py
class DataLoader(QThread):
totalSig = pyqtSignal(int)
countSig = pyqtSignal(int)
def __init__(self, parent=None):
super(DataLoader, self).__init__(parent)
self.threadactive = True
self.commitsize = 300
self.rowdata = []
def run(self):
self.totalSig.emit(1000)
print("Code Will Go Here For Loading the File")
# emulate process
for i in range(1000):
if self.threadactive:
QThread.msleep(10)
self.countSig.emit(i)
def stop(self):
self.threadactive = False
self.quit()
self.wait()
class PatDataLoader():
#staticmethod
def load(clientcode, filename):
fl = FileLoader()
fl.clientcode = clientcode
fl.filename = filename
fl.thread = DataLoader()
fl.loadData()
fl.exec_() # <---
main.py
#pyqtSlot()
def on_actionTest_triggered(self):
PatDataLoader.load("TEST","testfile.txt")