Search code examples
pythonpyqtpyqt4

How to make double arrow button in PyQt


I'm trying to make a button like this

enter image description here

Currently I can create the middle two buttons (single right or single left) using Qt::LeftArrow or Qt::RightArrow from setArrowType(). From the docs, there seems to only be 5 possible types. If this feature is not built in, how can I make a custom double arrow button?

Right now I have this

enter image description here

from PyQt4 import QtCore, QtGui
import sys

class PanningButton(QtGui.QToolButton):
    """Custom button with click, short/long press, and auto-repeat functionality"""

    def __init__(self):
        QtGui.QToolButton.__init__(self)
        self.setArrowType(QtCore.Qt.LeftArrow)
        # Enable auto repeat on button hold
        self.setAutoRepeat(True)
        # Initial delay in ms before auto-repetition kicks in
        self.setAutoRepeatDelay(700)
        # Length of auto-repetition
        self.setAutoRepeatInterval(500)
        self.clicked.connect(self.buttonClicked)
        self._state = 0

    def buttonClicked(self):
        # Panning
        if self.isDown():
            if self._state == 0:
                self._state = 1
                self.setAutoRepeatInterval(50)
        # Mouse release
        elif self._state == 1:
            self._state = 0
            self.setAutoRepeatInterval(125)

def pressed():
    global counter
    counter += 1
    print(counter)

if __name__ == '__main__':
    app = QtGui.QApplication([])

    counter = 0
    panning_button = PanningButton()
    panning_button.clicked.connect(pressed)

    panning_button.show()
    sys.exit(app.exec_())

Solution

  • There are several options:

    • Use the Qt icons, in this case you can use the standardIcon() of QStyle:
    from PyQt4 import QtCore, QtGui
    
    
    class Widget(QtGui.QWidget):
        def __init__(self, parent=None):
            super(Widget, self).__init__(parent)
            button1 = QtGui.QToolButton()
            button1.setIcon(
                button1.style().standardIcon(QtGui.QStyle.SP_MediaSeekBackward)
            )
    
            button2 = QtGui.QToolButton()
            button2.setArrowType(QtCore.Qt.LeftArrow)
    
            button3 = QtGui.QToolButton()
            button3.setArrowType(QtCore.Qt.RightArrow)
    
            button4 = QtGui.QToolButton()
            button4.setIcon(
                button1.style().standardIcon(QtGui.QStyle.SP_MediaSeekForward)
            )
    
            lay = QtGui.QHBoxLayout(self)
            for btn in (button1, button2, button3, button4):
                lay.addWidget(btn)
    
    
    if __name__ == "__main__":
        import sys
    
        app = QtGui.QApplication(sys.argv)
        w = Widget()
        w.show()
        sys.exit(app.exec_())
    

    enter image description here

    • Create the icons with QPainter
    def create_icon():
        pixmap = QtGui.QPixmap(QtCore.QSize(128, 128))
        pixmap.fill(QtCore.Qt.transparent)
        painter = QtGui.QPainter(pixmap)
        # draw icon
        painter.end()
        return QtGui.QIcon(pixmap)
    
    • Use icons created by an image editor like photoshop, corel draw, gimp, etc.

    IMHO the simplest solution is the last case since in the first case you are limited to what Qt provides, in the second case it can be unnecessarily complicated, however the third case is the optimal option.