In PyQt5 there are many ways to instantiate a QSlider.
(1) With no arguments, it will construct the default vertically oriented slider with no parent.
slider = QSlider()
# Equivalent to
# slider = QSlider(orientation=Qt.Vertical, parent=None)
(2) With a Qt.Orientation argument.
slider = QSlider(Qt.Horizontal)
# Equivalent to
# slider = QSlider(orientation=Qt.Horizontal, parent=None)
(3) With both Qt.Orientation and QWidget arguments.
window = QWidget()
slider = QSlider(Qt.Horizontal, window)
# Equivalent to
# slider = QSlider(orientation=Qt.Horizontal, parent=window)
This is all understandable, but then how is it also possible to pass just the second argument as a non keyword argument?
(4) With a QWidget argument.
window = QWidget()
slider = QSlider(window)
# Equivalent to
# slider = QSlider(orientation=Qt.Vertical, parent=window)
Is this an ability available to PyQt classes because they are really C++ classes with overloaded functions, or can this be emulated just in Python? I suppose for this particular case you can check the type of the first argument, and the constructor might look something like this:
class QSlider(QAbstractSlider):
def __init__(self, orientation=Qt.Vertical, parent=None):
if isinstance(orientation, QWidget):
parent = orientation
orientation = Qt.Vertical
super().__init__(parent)
# do stuff
But if both arguments accept the same type of object, then it doesn't work. So must a different type of object be used for each argument, or is there another way that this is achieved? If I want to subclass QSlider with another optional argument, and still retain all the possible QSlider constructors above, then more type checks are needed. Is the type checking the best way to enable constructing the class with all those options? The more arguments added the more tedious this becomes.
class MySlider(QSlider):
def __init__(self, x=1, orientation=Qt.Vertical, parent=None):
if isinstance(orientation, QWidget):
parent = orientation
orientation = Qt.Vertical
if isinstance(x, Qt.Orientation):
orientation = x
x = 1
elif isinstance(x, QWidget):
parent = x
x = 1
super().__init__(orientation, parent)
And now there is a problem due to Qt.Vertical/Qt.Horizontal also being integers:
>>> Qt.Horizontal
1
>>> isinstance(Qt.Horizontal, int)
True
Meaning QSlider(1)
would result in a horizontal slider. So someone calling MySlider(1)
might expect the same behavior, but in reality the 1 would be assigned to x
, and the orientation would still be vertical.