Im trying to make function, which passes 8 values to the progress bars in window app made with QtDesigner. That is there is a function which actually generates this values. I want to execute it every second in order to get theese values and update progress bars which displays values.
I combined tutorials about making a graphic app with Python and making an app with dynamically updating progess bars:
- Python Qt Development: https://www.youtube.com/watch?v=eD91nE8q8Nk
- PyQt Progress bar with Thread: https://www.youtube.com/watch?v=ivcxZSHL7jM
The problem is that values are passed correctly, but when it comes to send the signal, the whole app crashes with message:
Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)
Here is my code:
Module which generates the values (probkowanie.py):
import time from random import randint import threading def getSignals(): time.sleep(1) signals = (randint(0, 100), randint(0, 100), randint(0, 100), randint(0, 100), randint(0, 100), randint(0, 100), randint(0, 100), randint(0, 100), ) return signals
and here is main program code:
#!/usr/bin/env python # -*- coding: utf-8 -*- from PySide.QtCore import * from PySide.QtGui import * from PyQt4 import QtCore import sys import time import signalPreview # window library import probkowanie # values generating library class MainDialog(QDialog, signalPreview.Ui_mainDialog): def __init__(self, parent=None): super(MainDialog, self).__init__(parent) self.setupUi(self) self.threadclass = ThreadClass() self.threadclass.start() self.connect(self.threadclass, QtCore.SIGNAL('MYO_SIGNALS'), self.updateProgressBars) def updateProgressBars(self, signals): self.progressBar.setValue(signals[0]) class ThreadClass(QtCore.QThread): def __init__(self, parent = None): super(ThreadClass, self).__init__(parent) def run(self): while 1: signals = probkowanie.getSignals() self.emit(QtCore.SIGNAL('MYO_SIGNALS'), 5) # this line causes crash print signals # it works correctly app = QApplication(sys.argv) form = MainDialog() form.show() app.exec_()
I think it may be caused by mixing libraries. I use QtCore from PySide even though tutorial number 2 is based on PyQt4. My decision is because tutorial number 1 is based on PySide. I tried changing:
from PySide import QtCore
to
from PyQt4 import QtCore
but then I get another bunch of errors, which I don’t know what to do with:
Traceback (most recent call last): File "/usr/lib/pycharm/helpers/pydev/pydevd.py", line 1580, in <module> globals = debugger.run(setup['file'], None, None, is_module) File "/usr/lib/pycharm/helpers/pydev/pydevd.py", line 964, in run pydev_imports.execfile(file, globals, locals) # execute the script File "/mnt/Grubas/Projekty/Biomed/MYO/myo.py", line 36, in <module> form = MainDialog() File "/mnt/Grubas/Projekty/Biomed/MYO/myo.py", line 20, in __init__ self.connect(self.threadclass, QtCore.SIGNAL('MYO_SIGNALS'), self.updateProgressBars) TypeError: 'PySide.QtCore.QObject.connect' called with wrong argument types: PySide.QtCore.QObject.connect(ThreadClass, str, instancemethod) Supported signatures: PySide.QtCore.QObject.connect(PySide.QtCore.QObject, str, callable, PySide.QtCore.Qt.ConnectionType = Qt.AutoConnection) PySide.QtCore.QObject.connect(PySide.QtCore.QObject, PySide.QtCore.QMetaMethod, PySide.QtCore.QObject, PySide.QtCore.QMetaMethod, PySide.QtCore.Qt.ConnectionType = Qt.AutoConnection) PySide.QtCore.QObject.connect(PySide.QtCore.QObject, str, PySide.QtCore.QObject, str, PySide.QtCore.Qt.ConnectionType = Qt.AutoConnection) PySide.QtCore.QObject.connect(PySide.QtCore.QObject, str, str, PySide.QtCore.Qt.ConnectionType = Qt.AutoConnection) PySide.QtCore.QObject.connect(str, callable, PySide.QtCore.Qt.ConnectionType = Qt.AutoConnection) PySide.QtCore.QObject.connect(str, PySide.QtCore.QObject, str, PySide.QtCore.Qt.ConnectionType = Qt.AutoConnection)
@EDIT After providing changes proposed by @ekhumoro script doens’t crash, but now I’m getting another error:
QObject::connect: Cannot queue arguments of type ‘object’ (Make sure ‘object’ is registered using qRegisterMetaType().)
I tried to look for solution on my own, but I didn’t find the exact code which I need. I also tried transforming type of signal from (object) to (tuple) or (list), but it leads to another errors:
TypeError: Unknown type used to call meta function (that may be a signal): tuple
The most solutions I found are based on PyQT. Is there an easy way to rewrite it for PySide? Here is an example of solution, which seems to be correct but is made using PyQT: https://stackoverflow.com/a/2595607/2550466
Advertisement
Answer
You are right to think that mixing PySide and PyQt will cause problems, so you will need to remove one of them. However, the crash itself is probably caused by a bug in PySide. There is an SO question with a similar problem shown here:
So you also need to change the way you define and emit MYO_SIGNALS
.
Below is a fixed version of your script (the changed lines are commented):
# from PySide.QtCore import * # from PySide.QtGui import * # from PyQt4 import QtCore from PyQt4.QtCore import * from PyQt4.QtGui import * import sys import time import signalPreview # window library import probkowanie # values generating library class MainDialog(QDialog): def __init__(self, parent=None): super(MainDialog, self).__init__(parent) self.setupUi(self) self.threadclass = ThreadClass() self.threadclass.start() # self.connect(self.threadclass, QtCore.SIGNAL('MYO_SIGNALS'), self.updateProgressBars) self.connect(self.threadclass, SIGNAL('MYO_SIGNALS'), self.updateProgressBars) def updateProgressBars(self, signals): self.progressBar.setValue(signals[0]) # class ThreadClass(QtCore.QThread): class ThreadClass(QThread): def __init__(self, parent = None): super(ThreadClass, self).__init__(parent) def run(self): while 1: signals = probkowanie.getSignals() # self.emit(QtCore.SIGNAL('MYO_SIGNALS'), 5) # this line causes crash self.emit(SIGNAL('MYO_SIGNALS'), signals) print signals # it works correctly app = QApplication(sys.argv) form = MainDialog() form.show() app.exec_()