PyQt5 QMainWindow/QAxWidget thread problem - python

I want to have different thread between QMainWindow and QAxWidget.
As I know, QMainWindow should have MainThread.
So I write down code as below.
from PyQt5 import QtCore, QtGui, QtWidgets
import sys
class Main_Thread(QtWidgets.QMainWindow):
def __init__(self):
# setting QMainWindow with widgets... + super().__init__()
sub_instance = Sub_Thread()
sub_thread = QtCore.QThread()
sub_instance.moveToThread(sub_thread)
sub_thread.started.connect(sub_instance.run)
sub_thread.start()
class Sub_Thread(QObject):
def __init__(self):
super().__init__()
def run(self):
ocx = QAxContainer.QAxWidget('connection path')
ocx.signal.connect(slot) # line★
ocx(AcitveX) have a lot of signal...
I have error that ocx has no that kind of signal when I write 'line★'
What that kind of problem is occurring?
ocx should be made in MainThread?

Related

PYQT5 Signals & Slots are not working even though i followed the documentation

I am trying to send signal and receive it between two windows, i followed exactly the documentation.
While running the program : No error Nor receiving the signal in the slot
While Debugging in #pycharm: i receive below error :
TypeError: connect() failed between started() and _signal()
Two files Codes are below:
First file name: Signals.py
import sys
from PyQt5 import QtWidgets as qtw
from PyQt5 import QtCore as qtc
import slots
class aaa(qtw.QWidget,qtc.QObject):
submitted = qtc.pyqtSignal(str)
def __init__(self):
super().__init__()
self.setLayout(qtw.QVBoxLayout())
self.edit = qtw.QLineEdit()
self.submit=qtw.QPushButton('Submit',clicked=self.onSubmit)
self.layout().addWidget(self.edit)
self.layout().addWidget(self.submit)
self.show()
def onSubmit(self):
self.submitted.emit(self.edit.text())
self.close()
self.myDialog2 = slots.bbb()
if __name__ == '__main__':
app = qtw.QApplication(sys.argv)
mw = aaa()
sys.exit(app.exec())
Second file name: slots.py
from PyQt5 import QtWidgets as qtw
from PyQt5 import QtCore as qtc
import Signals
class bbb(qtw.QWidget,qtc.QThread):
#qtc.pyqtSlot()
def __init__(self):
super().__init__()
self.setLayout(qtw.QVBoxLayout())
self.label = qtw.QLabel(self)
self.x=Signals.aaa()
self.x.submitted.connect(self.label.setText)
print(self.label.text())
self.layout().addWidget(self.label)
self.show()
I do not know what documentation refers to the OP so I could not indicate if the tutorial you are following is correct or not. If you are referring to the official docs then you clearly have not followed it correctly.
Your code has many errors so I will only mention the most important ones:
The connection must be used before emitting the signal,
You should not inherit from QObject and QWidget since they will have conflicts, in addition to that there is no justification.
You shouldn't use pyqtSlot unnecessarily, setting it in the contstructor doesn't make sense.
You are creating a circular import.
"self.x" is not "mw" but another object.
A possible solution is the following:
from PyQt5 import QtWidgets as qtw
from PyQt5 import QtCore as qtc
class bbb(qtw.QWidget):
def __init__(self):
super().__init__()
lay = qtw.QVBoxLayout(self)
self.label = qtw.QLabel()
lay.addWidget(self.label)
import sys
from PyQt5 import QtWidgets as qtw
from PyQt5 import QtCore as qtc
import slots
class aaa(qtw.QWidget, qtc.QObject):
submitted = qtc.pyqtSignal(str)
def __init__(self):
super().__init__()
self.edit = qtw.QLineEdit()
self.submit = qtw.QPushButton("Submit", clicked=self.onSubmit)
lay = qtw.QVBoxLayout(self)
lay.addWidget(self.edit)
lay.addWidget(self.submit)
self.myDialog2 = slots.bbb()
self.submitted.connect(self.myDialog2.label.setText)
def onSubmit(self):
self.submitted.emit(self.edit.text())
self.close()
self.myDialog2.show()
if __name__ == "__main__":
app = qtw.QApplication(sys.argv)
mw = aaa()
mw.show()
sys.exit(app.exec())

PyQt5 - how to avoid crashing gui while updating progresssbar in a multi-threading setting (Qthread)?

I am new in multi threading. The video file I use work fine and the progress-bar at the start shows a percent in progress-bar. When I want to change the progress-bar value continuously for example the current cpu usage value the below code keeps crashing when i run the code. Why is the code not working??
I think the problem is emit and connect. If so what can i do? And how do I correct this? Thanks in advance for the help.
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import QObject, pyqtSignal
import sysinfo
from multi import Ui_Form
class main(QtWidgets.QWidget ,Ui_Form):
cpu_value = pyqtSignal()
def __init__(self, parent = None):
super(main,self).__init__(parent)
self.setupUi(self)
self.threadclass = ThreadClass()
self.threadclass.start()
self.cpu_value.connect(self.updateProgressBar)
def updateProgressBar(self):
val = sysinfo.getCPU()
self.progressBar.setValue(val)
class ThreadClass(QtCore.QThread):
def __init__(self, parent = None):
super(ThreadClass,self).__init__(parent)
def run(self):
while 1:
val = sysinfo.getCPU()
self.cpu_value.emit(val)
if __name__ == '__main__':
a = QtWidgets.QApplication(sys.argv)
app = main()
app.show()
a.exec_()
env: python3.5 + pyqt5.9
I use a timer to update the CPU info like that:
#!/usr/bin/python3
# 2017.12.10 13:20:11 CST
# 显示 CPU
import sys
from PyQt5 import QtCore, QtWidgets
import psutil
class CPU(QtWidgets.QProgressBar):
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowTitle("CPU Info")
self.timer = QtCore.QTimer(self)
self.timer.timeout.connect(lambda : self.setValue(psutil.cpu_percent()))
self.timer.start(1000)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
win = CPU()
win.show()
app.exec_()

PyQt4: inheriting QThread

I have a QWidget which calls some python code using a QThread. This code then also does some logic and calls another class. In this class, I want to pass a signal up to my QWidget, so that "Hello World" is printed. The code as it stands gives the error sm instance has no attribute 'sayHello', which I know - I'm just pretty clueless how to make the run method call a different class so that all the signals work.
widget.py
from prog import TaskThread
from PyQt4 import QtCore, QtGui
class MyWidget(QtGui.QWidget):
def __init__(self):
self.btn = QtGui.QPushButton('Run!', self)
self.btn.clicked.connect(self.onStart)
self.myLongTask = TaskThread()
self.myLongTask.sayHello.connect(self.sayHi)
def onStart(self):
self.myLongTask.start()
def sayHi(self):
print "hello world"
prog.py
from PyQt4 import QtCore
from sm import sc
class TaskThread(QtCore.QThread):
sayHello = QtCore.pyqtSignal()
def run(self):
sm.sc()
sm.py
class sc():
def __init__(self):
for i in range(0,50):
print i
if i == 5: self.sayHello.emit()
I had to change your code slightly to get it to run on my machine but manually passing the signal instance to the sc class definitely raises the signal. The output may be interleaved with the printing of the i loop.
widget.py
from prog import TaskThread
import sys
from PyQt4 import QtCore, QtGui
class flexemWidget(QtGui.QWidget):
def __init__(self):
super(flexemWidget, self).__init__()
self.btn = QtGui.QPushButton('Run!', self)
self.btn.clicked.connect(self.onStart)
self.myLongTask = TaskThread()
self.myLongTask.sayHello.connect(self.sayHi)
self.show()
def onStart(self):
self.myLongTask.start()
def sayHi(self):
print "hello world"
app = QtGui.QApplication(sys.argv)
ex = flexemWidget()
sys.exit(app.exec_())
prog.py
from PyQt4 import QtCore
from sm import sc
class TaskThread(QtCore.QThread):
sayHello = QtCore.pyqtSignal()
def run(self):
sc(self.sayHello)
sc.py
from PyQt4 import QtCore
class sc():
def __init__(self, signal):
for i in range(0,50):
print i
if i == 5: signal.emit()

textChanged event not triggering in Pyqt4

How come the textChanged event is not happening whenever I input some data in the QLineEdit?
from PyQt4.Qt import Qt, QObject,QLineEdit
from PyQt4.QtCore import pyqtSlot,SIGNAL,SLOT
from PyQt4 import QtGui, QtCore
import sys
class DirLineEdit(QLineEdit, QtCore.QObject):
"""docstring for DirLineEdit"""
#pyqtSlot(QtCore.QString)
def textChanged(self, string):
QtGui.QMessageBox.information(self,"Hello!","Current String is:\n"+string)
def __init__(self):
super(DirLineEdit, self).__init__()
self.connect(self,SIGNAL("textChanged(QString&)"),
self,SLOT("textChanged(QString *)"))
app = QtGui.QApplication(sys.argv)
smObj = DirLineEdit()
smObj.show()
app.exec_()
everything seems to be correct to me, what am I missing ?
Replace following line:
self.connect(self,SIGNAL("textChanged(QString&)"),
self,SLOT("textChanged(QString *)"))
with:
self.connect(self,SIGNAL("textChanged(QString)"),
self,SLOT("textChanged(QString)"))
Or you can use self.textChanged.connect (handler should be renamed because the name conflicts):
class DirLineEdit(QLineEdit, QtCore.QObject):
def on_text_changed(self, string):
QtGui.QMessageBox.information(self,"Hello!","Current String is:\n"+string)
def __init__(self):
super(DirLineEdit, self).__init__()
self.textChanged.connect(self.on_text_changed)

Creating widgets in a different class

I have the mainwindow in the 'DataClass'.How can I create widgets in another class(the HelloClass)
test.py
import sys
import label
from PyQt4 import QtGui, QtCore
class DataClass(QtGui.QMainWindow):
def __init__(self):
super(DataClass, self).__init__()
self.window()
def window(self):
ex=label.HelloClass(self)
ex.print_label()
def main():
app = QtGui.QApplication(sys.argv)
ob=DataClass()
ob.show()
sys.exit(app.exec_())
if __name__=='__main__':
main()
and this is the 'label.py' file:
import sys
from PyQt4 import QtGui, QtCore
class HelloClass(QtGui.QMainWindow):
def print_label(self):
self.la=QtGui.QLabel("hello",self)
self.la.move(300,100)
self.la.show()
import sys
from PyQt4 import QtGui, QtCore
class HelloClass(QtGui.QMainWindow):
def print_label(self):
self.la=QtGui.QLabel("hello",self)
self.la.move(300,100)
self.la.show()
You can't have two QMainWindow class, you should just not inherit from QMainWindow on HelloClass. And if you are setting parent to label then set it your DataClass which is your QMainWindow.
class HelloClass(object):
def print_label(self, parent):
self.la = QtGui.QLabel("hello", parent)
self.la.move(300, 100)
self.la.show()
class DataClass(QtGui.QMainWindow):
def __init__(self):
super(DataClass, self).__init__()
self.window()
def window(self):
ex = label.HelloClass()
ex.print_label(self)
But to be honest, the best way to create GUI using PyQt is to use QtDesigner. Create your .ui file with QtDesigner and then create .py file with command pyuic4 your.ui -o ui_your.py.
-- UPDATE --
Your controller class for using gui created by QtDesigner would look like this:
from ui_objects import Ui_Objects # this is class created with QtDesigner, name of class is a 'Ui_' + name of main Object in QtDesigner
class Objects(QtGui.QWidget):
def __init__(self):
QtGui.QWidget.__init__(self)
self.ui = Ui_Objects()
self.ui.setupUi(self)
# then you can add your own code, in example connect your own methods to actions for widgets

Categories

Resources