I'm currently trying to convert an old python program from Python 2 to Python 3, and update from PyQt4 to PyQt5. The application uses the old style signal and slots that are not supported under PyQt5. I have figured out most of what needs to be done, but below are a few lines that I can't seem to get working:
self.emit(SIGNAL('currentChanged'), row, col)
self.emit(SIGNAL("activated(const QString &)"), self.currentText())
self.connect(self,SIGNAL("currentChanged(const QString&)"), self.currentChanged)
The top two lines, I have no idea where to start since they don't seem to be attached to anything. The last example I'm not quite sure what to do with (const QString &
).
I'm not entirely sure how to approach these, and I'm still learning python, but any help would be appreciated.
EDIT: The documentation doesn't really seem to go into depth on these cases, at least in a way that I understand.
The exact answer to this will depend on what kind of object self
is. If it is a Qt class that already defines those signals, then the new-style syntax would be this:
self.currentChanged[int, int].emit(row, col)
self.activated[str].emit(self.currentText())
self.currentChanged[str].connect(self.handleCurrentChanged)
However, if any of those aren't pre-defined, you would need to define custom signals for them, like this:
class MyClass(QWidget):
# this defines two overloads for currentChanged
currentChanged = QtCore.pyqtSignal([int, int], [str])
activated = QtCore.pyqtSignal(str)
def __init__(self, parent=None):
super(MyClass, self).__init__(parent)
self.currentChanged[str].connect(self.handleCurrentChanged)
def handleCurrentChanged(self, text):
print(text)
The old-style syntax allowed custom signals to be emitted dynamically (i.e. without defining them first), but that is not possible any more. With the new-style syntax, custom signals must always be explicitly defined.
Note that, if there is only one overload defined for a signal, the selector can be omitted:
self.activated.emit(self.currentText())
For more information, see these articles in the PyQt Docs:
EDIT:
For your actual code, you need to make the following changes for the currentChanged
signals:
In Multibar.py (around line 30):
This defines a custom signal (because QWidget
does not have it):
class MultiTabBar(QWidget):
# add the following line
currentChanged = pyqtSignal(int, int)
In Multibar.py (around line 133):
This emits the custom signal defined in (1):
# self.emit(SIGNAL('currentChanged'), row, col)
self.currentChanged.emit(row, col)
In ScWindow.py (around line 478):
This connects the signal defined in (1):
# self.connect(self.PieceTab,SIGNAL("currentChanged"),self.pieceTabChanged)
self.PieceTab.currentChanged.connect(self.pieceTabChanged)
In ItemList.py (around line 73):
The QFileDialog
class already defines this signal, and there is only one overload of it. But the name of the slot must be changed, because it is shadowing the built-in signal name (which has become an attribute in the new-style syntax). So the connection should be made like this:
# self.connect(self,SIGNAL("currentChanged(const QString&)"),self.currentChanged)
self.currentChanged.connect(self.onCurrentChanged)
In ItemList.py (around line 78):
This renames the slot for the connection made in (4):
# def currentChanged(self, file):
def onCurrentChanged(self, file):