Home > PyQt5, python > PyQt5: QPushButton

PyQt5: QPushButton

11 Marzo 2019

Torna all’indice degli appunti

QPushButton è il widget relativo al bottone.
Creare un bottone è molto semplice

from PyQt5.QtWidgets import QMainWindow, QPushButton
import sys


class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent=parent)
        self.setWindowTitle("QButton Example")
        self.central_widget = FormWidget(self) 
        self.setCentralWidget(self.central_widget)
        self.resize(200, 100)


class FormWidget(QWidget):
    def __init__(self, parent=None):
        super(FormWidget, self).__init__(parent=parent)
        layout = QBoxLayout(QBoxLayout.TopToBottom)
        self.setLayout(layout)
        self.button = QPushButton(text="Quit", parent=self)
        layout.addWidget(self.button)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    main_window = MainWindow()
    main_window.show()
    sys.exit(app.exec_())

Dimensioni

Per modificare le dimensioni del pulsante è possibile usare il metodo setFixedSize:

...
        self.button = QPushButton(text="Quit", parent=self)
        self.button.setFixedSize(200, 100)
        layout.addWidget(self.button)
...

Testo bottone

Per modificare il testo del bottone, si utilizza il metodo setText

...
        self.button = QPushButton(text="Quit", parent=self)
        self.button.setFixedSize(200, 100)
        layout.addWidget(self.button)
        self.button.setText("QUIT")
...

Segnali

I segnali principali legati all’utilizzo di un bottone sono:
clicked, pressed, released.
Questi segnali sono oggetti pyqtSignal e vengono connessi al widget tramite il metodo connect:

...

class FormWidget(QWidget):
    def __init__(self, parent=None):
        super(FormWidget, self).__init__(parent=parent)
        layout = QBoxLayout(QBoxLayout.TopToBottom)
        self.setLayout(layout)
        self.button = QPushButton("Quit", self)  # args: text of button, parent
        self.button.setFixedSize(200, 100)
        self.button.setText("QUIT")
        layout.addWidget(self.button)

        self.button.clicked.connect(self.on_click)
        self.button.pressed.connect(self.on_press)
        self.button.released.connect(self.on_release)

    def on_click(self):
        print("INFO: button clicked")

    def on_press(self):
        print("INFO: button pressed")

    def on_release(self):
        print("INFO: button released")
...

ShortCut

E’ possibile assegnare una shortcut al bottone per avviare l’azione ad esso collegata.
Semplicemente basta anteporre al testo del bottone il l’ampersand &:

...

        self.button.setText("&Quit")
        layout.addWidget(self.button)
...

Colorazione bottone

E’ possibile modificare il colore del bottone tramite il metodo setStyleSheet, come se si utilizzasse la sintassi css. La colorazione è esprimibile con le tre forme:

self.button.setStyleSheet("background-color: pink; color: blue")
self.button.setStyleSheet("background-color: rgb(255, 204, 204); color: blue")
self.button.setStyleSheet("background-color: #ffcccc; color: blue")

Una vale l’altra, percui:

self.button.setStyleSheet("background-color: pink; color: blue")
self.button.setStyleSheet("background-color: rgb(255, 204, 204); color: blue")
self.button.setStyleSheet("background-color: #ffcccc; color: blue")
from PyQt5.QtWidgets import QWidget, QApplication, QBoxLayout, QPushButton
from PyQt5.QtWidgets import QMainWindow
import sys


class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent=parent)
        self.setWindowTitle("QButton Example")
        self.central_widget = FormWidget(self) 
        self.setCentralWidget(self.central_widget)
        self.resize(200, 100)


class FormWidget(QWidget):
    def __init__(self, parent=None):
        super(FormWidget, self).__init__(parent=parent)
        layout = QBoxLayout(QBoxLayout.TopToBottom)
        self.setLayout(layout)
        self.button = QPushButton("Quit", self)  # args: text of button, parent
        self.button.setFixedSize(200, 100)
        self.button.setText("QUIT")
        self.button.setStyleSheet("background-color: #ffcccc; color: blue")
        layout.addWidget(self.button)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    main_window = MainWindow()
    main_window.show()
    sys.exit(app.exec_())


Attenzione:
Questo tipo di modifica, incide sullo stile stesso del bottone, tant’è vero che è possibile modificarlo
pesantemente:

...
        self.button = QPushButton("Quit", self)  # args: text of button, parent
        self.button.setFixedSize(200, 100)
        self.button.setText("QUIT")

        new_btn_ss = """QPushButton{background-color: pink;
                                    border-style: outset;
                                    border-width: 2px;
                                    border-radius: 15px;
                                    border-color: brown;
                                    font: bold 14px;
                                    min-width: 10em;
                                    padding: 6px;}
                        QPushButton:pressed {background-color: rgb(224, 0, 0);
                                             border-style: inset;}
                     """
        self.button.setStyleSheet(new_btn_ss)
        layout.addWidget(self.button)
...

Se non vogliamo influenzare lo stile del widget, possiamo utilizzare palette, per
fare la stessa cosa. I passi sono i seguenti:

1. si crea un oggetto QColor del colore desiderato;
2. si ottiene un oggetto QPalette direttamente dal widget desiderato;
3. si decide su quale porzione del widget lavorare, nel nostro caso il background;
4. tramite l’ggetto palette, associamo il background al colore desiderato;
5. settiamo questa associazione al widget desiderato


...
from PyQt5.QtGui import QColor

...
        self.button.setText("QUIT")

        color = QColor('Red')  # create a Red Qcolor object
        palette = self.button.palette()  # get a QPalette object
        role = self.button.backgroundRole()  # get the button background
        palette.setColor(role, color)  # link role and color in the palette
        self.button.setPalette(palette)  # set the palette to the button
        self.button.setAutoFillBackground(True)

        layout.addWidget(self.button)
...

Attenzione:
Alcuni stili non usano palette perchè utilizzano il theme-engine nativo, come nel caso di xp, Seven, OS X.
Questo risulta nella sola colorazione del bordo.
Qualora su Seven si volesse colorare interamente il bottone, si dovrà utilizzare il primo metodo visto.

Modificare il background al passaggio del mouse:

Per ottenere questo effetto è possibile subclassare QPushButton e
sovrascrivere gli eventi enterEvent e leaveEvent
già esistenti

from PyQt5.QtWidgets import QMainWindow
from PyQt5.QtWidgets import (QWidget, QApplication, QBoxLayout, QPushButton,
                             )
from PyQt5.QtGui import QColor, QPalette
from PyQt5.QtCore import pyqtSignal
import sys


class HoverButton(QPushButton):
    mouseHover = pyqtSignal(bool)

    def __init__(self, text, parent):
        QPushButton.__init__(self, text, None)
        self.color = QColor('Red')

    def enterEvent(self, event):
        self.color = QColor('Green')
        self.complete_style()

    def leaveEvent(self, event):
        self.color = QColor('Red')
        self.complete_style()

    def complete_style(self):
        palette = QPalette()
        palette.setColor(palette.Button, self.color)
        self.setPalette(palette)
        self.setAutoFillBackground(True)


class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.setWindowTitle("QButton Example")
        self.central_widget = FormWidget(self)
        self.setCentralWidget(self.central_widget)
        self.resize(200, 100)


class FormWidget(QWidget):
    def __init__(self, parent):
        super(FormWidget, self).__init__(parent)
        layout = QBoxLayout(QBoxLayout.TopToBottom)
        self.setLayout(layout)
        self.button = HoverButton("Quit", self)
        color = QColor('Red')
        palette = self.button.palette()
        role = self.button.backgroundRole()
        palette.setColor(role, color)
        self.button.setPalette(palette)
        self.button.setAutoFillBackground(True)

        self.button.setFixedSize(200, 100)
        self.button.setFlat(False)
        self.button.clicked.connect(self.on_click)
        layout.addWidget(self.button, 0)

    def on_click(self):
        print("INFO: Clicked!")


if __name__ == '__main__':
    app = QApplication(sys.argv)
    main_window = MainWindow()
    main_window.show()
    sys.exit(app.exec_())

Toggled button

Per fermare la posizione del pulsante e giocare sull’effetto toggle, è possibile utilizzare il metodo setCheckable. Così facendo sarà possibile utilizzare il segnale toggled del widget per chiamare la callback assegnata e modificare l’aspetto del bottone.
Questa callback semplicemente controlla lo stato del flag checked. Se questo è True, ovvero ho cliccato il bottone, lo colora in un modo e ne modifico il testo, quando riclicco sul bottone lo riporto allo stile di partenza.
Ovviamente lo stile è personalizzabile più o meno in profondità.

...
        self.button = QPushButton("&Quit", self)
        self.button.setCheckable(True)  # toggled signal enabled
        ...
        self.button.clicked.connect(self.on_click)
        self.button.toggled.connect(self.on_click_toggle)  # callback activated

...
    def on_click_toggle(self):
        checked = self.button.isChecked()
        color = QColor('Blue') if checked else QColor('Red')
        text = "Clicked" if checked else "Quit"
        palette = self.button.palette()
        role = self.button.backgroundRole()
        palette.setColor(role, color)
        self.button.setPalette(palette)
        self.button.setText(text)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    main_window = MainWindow()
    main_window.show()
    sys.exit(app.exec_())

Associare Menu ad un bottone

E’ molto semplice utilizzando QMenu. I passi sono i seguenti:

1. Si crea un oggetto QMenu e con il metodo addAction, si creano le voci del menu;
2. Con il metodo setMenu del botton, si aggiunge l’istanza di QMenu, al bottone stesso;
3. si creano le callback che abbiamo precedentemente definito con il metodo addAction.

from PyQt5.QtWidgets import QMainWindow
from PyQt5.QtWidgets import (QWidget, QApplication, QBoxLayout, QPushButton,
                             QMenu)
import sys


class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.setWindowTitle("QButton Example")
        self.central_widget = FormWidget(self)
        self.setCentralWidget(self.central_widget)
        self.resize(200, 100)


class FormWidget(QWidget):
    def __init__(self, parent):
        super(FormWidget, self).__init__(parent)
        layout = QBoxLayout(QBoxLayout.TopToBottom)
        self.setLayout(layout)
        self.button = QPushButton("Actions", self)
        self.button.setFixedSize(200, 100)
        self.button.setFlat(False)
        menu = QMenu()
        menu.addAction('Info', self.on_info)
        menu.addAction('Exit', self.on_exit)
        self.button.setMenu(menu)

        layout.addWidget(self.button, 0)

    def on_info(self):
        print("INFO: Info action selected")

    def on_exit(self):
        print("INFO: Exit action selected")

if __name__ == '__main__':
    app = QApplication(sys.argv)
    main_window = MainWindow()
    main_window.show()
    sys.exit(app.exec_())

ICona e ToolTip

Per associare una icona ad un bottone, si crea un oggetto QIcon e lo si associa al bottone stesso, con il metodo setIcon.
Stesso discorso per il ToolTip: si associa il testo del tooltip al bottone utilizzando il metodo setToolTip:

...
from PyQt5.QtGui import QIcon
...
        self.button = QPushButton("&Quit", self)

        self.button.setIcon(QIcon("exit24.png"))
        self.button.setToolTip("Exit from Application")
...

Torna all’indice degli appunti

Categorie:PyQt5, python Tag: ,
I commenti sono chiusi.