QT Widgets¶
Exploring Widgets in PyQt6¶
PyQt6
offers a wide range of widgets
that you can use to build interactive graphical user interfaces (GUIs).
In this section, we'll explore some commonly used widgets and provide examples of how to use them.
A quick demo¶
import sys
from PyQt6.QtCore import Qt
from PyQt6.QtWidgets import (
QApplication,
QCheckBox,
QComboBox,
QDateEdit,
QDateTimeEdit,
QDial,
QDoubleSpinBox,
QFontComboBox,
QLabel,
QLCDNumber,
QLineEdit,
QMainWindow,
QProgressBar,
QPushButton,
QRadioButton,
QSlider,
QSpinBox,
QTimeEdit,
QVBoxLayout,
QWidget,
)
# Subclass QMainWindow to customize your application's main window
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Widgets App")
layout = QVBoxLayout()
widgets = [
QCheckBox,
QComboBox,
QDateEdit,
QDateTimeEdit,
QDial,
QDoubleSpinBox,
QFontComboBox,
QLCDNumber,
QLabel,
QLineEdit,
QProgressBar,
QPushButton,
QRadioButton,
QSlider,
QSpinBox,
QTimeEdit,
]
for w in widgets:
layout.addWidget(w())
widget = QWidget()
widget.setLayout(layout)
# Set the central widget of the Window. Widget will expand
# to take up all the space in the window by default.
self.setCentralWidget(widget)
app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec()
Lets have a look at all the example
widgets
, from top to bottom:Widget What it does QCheckbox
A checkbox QComboBox
A dropdown list box QDateEdit
For editing dates and datetimes QDateTimeEdit
For editing dates and datetimes QDial
Rotatable dial QDoubleSpinBox
A number spinner for floats QFontComboBox
A list of fonts QLCDNumber
A quite ugly LCD display QLabel
Just a label, not interactive QLineEdit
Enter a line of text QProgressBar
A progress bar QPushButton
A button QRadioButton
A toggle set, with only one active item QSlider
A slider QSpinBox
An integer spinner QTimeEdit
For editing times
QLabel:¶
QLabel
is used to display text or images. Here's an example of how to create a QLabel
:
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.setWindowTitle("My App")
widget = QLabel("Hello")
font = widget.font()
font.setPointSize(30)
widget.setFont(font)
widget.setAlignment(Qt.AlignmentFlag.AlignHCenter | Qt.AlignmentFlag.AlignVCenter)
self.setCentralWidget(widget)
- Customizing Font:
You can customize the
font
used byQLabel
to make your text stand out. Here's how you can set the font for a QLabel:
label = QLabel('Hello, PyQt5!')
font = QFont('Arial', 16) # Set font family and size
label.setFont(font)
The alignment is specified by using a flag from the
Qt.AlignmentFlag
.You can combine flags together using pipes (
|
), however note that you can only usevertical
orhorizontal alignment flag
at a time.The flags available for horizontal alignment are:
PyQt6 flag (horizontal alignment) Behavior Qt.AlignmentFlag.AlignLeft
Aligns with the left edge. Qt.AlignmentFlag.AlignRight
Aligns with the right edge. Qt.AlignmentFlag.AlignHCenter
Centers horizontally in the available space. Qt.AlignmentFlag.AlignJustify
Justifies the text in the available space. PyQt6 flag (vertical alignment) Behavior Qt.AlignmentFlag.AlignTop
Aligns with the top. Qt.AlignmentFlag.AlignBottom
Aligns with the bottom. Qt.AlignmentFlag.AlignVCenter
Centers vertically in the available space. Qt.AlignmentFlag.AlignCenter
Centers horizontally
andvertically
.You can also use
QLabel
to display an image using.setPixmap()
.- This accepts an
pixmap
, which you can create by passing an image filename toQPixmap
.
- This accepts an
widget.setPixmap(QPixmap('otje.jpg'))
QCheckBox¶
QCheckBox()
presents a checkable box to the user.
You can set a checkbox state programmatically using .setChecked
or .setCheckState
.
The former accepts either
True
orFalse
representing checked or unchecked, respectively.However, with
.setCheckState
you also specify a particular checked state using aQt.CheckState flag
:- If you set the value to
Qt.CheckState.PartiallyChecked
the checkbox will becometristate
. - You can also set a checkbox to be tri-state without setting the current state to partially checked by using
.setTriState(True)
PyQt6 flag (long name) Behavior Qt.CheckState.Unchecked
Item is unchecked Qt.CheckState.PartiallyChecked
Item is partially checked Qt.CheckState.Checked
Item is checked - If you set the value to
Example
class MainWindow(QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.setWindowTitle("My App") widget = QCheckBox() widget.setCheckState(Qt.CheckState.Checked) # For tristate: widget.setCheckState(Qt.PartiallyChecked) # Or: widget.setTriState(True) widget.stateChanged.connect(self.show_state) self.setCentralWidget(widget) def show_state(self, s): print(s == Qt.CheckState.Checked.value) print(s)
QComboBox¶
The QComboBox
is a drop down list, closed by default with an arrow to open it. It is suited to selection of a choice from a long list of options.
Example
- The
.currentIndexChanged
signal is triggered when the currently selected item is updated, by default passing theindex
of the selected item in the list. - There is also a
.currentTextChanged
signal which instead provides thelabel
of the currently selected item, which is often more useful.
class MainWindow(QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.setWindowTitle("My App") widget = QComboBox() widget.addItems(["One", "Two", "Three"]) # Sends the current index (position) of the selected item. widget.currentIndexChanged.connect( self.index_changed ) # There is an alternate signal to send the text. widget.currentTextChanged.connect( self.text_changed ) self.setCentralWidget(widget) def index_changed(self, i): # i is an int print(i) def text_changed(self, s): # s is a str print(s)
- The
You can also limit the number of items allowed in the box by using .setMaxCount, e.g.
widget.setMaxCount(10)
QListWidget¶
This widget is similar to
QComboBox
, except options are presented as a scrollable list of items.- It also supports selection of multiple items at once.
- A
QListWidget
offers ancurrentItemChanged
signal which sends theQListWidgetItem
(the element of the list widget), and acurrentTextChanged
signal which sends thetext
of the current item.
Example
class MainWindow(QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.setWindowTitle("My App") widget = QListWidget() widget.addItems(["One", "Two", "Three"]) widget.currentItemChanged.connect(self.index_changed) widget.currentTextChanged.connect(self.text_changed) self.setCentralWidget(widget) def index_changed(self, i): # Not an index, i is a QListWidgetItem print(i.text()) def text_changed(self, s): # s is a str print(s)
QLineEdit¶
The QLineEdit
widget is a simple single-line text editing box, into which users can type input.
The
QLineEdit
has a number ofsignals
available for different editing events including when return is pressed (by the user), when the user selection is changed.There are also two edit
signals
, one for when the text in the box has been edited and one for when it has been changed.Example
class MainWindow(QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.setWindowTitle("My App") widget = QLineEdit() widget.setMaxLength(10) widget.setPlaceholderText("Enter your text") #widget.setReadOnly(True) # uncomment this to make readonly widget.returnPressed.connect(self.return_pressed) widget.selectionChanged.connect(self.selection_changed) widget.textChanged.connect(self.text_changed) widget.textEdited.connect(self.text_edited) self.setCentralWidget(widget) def return_pressed(self): print("Return pressed!") self.centralWidget().setText("BOOM!") def selection_changed(self): print("Selection changed") print(self.centralWidget().selectedText()) def text_changed(self, s): print("Text changed...") print(s) def text_edited(self, s): print("Text edited...") print(s)
Additionally, it is possible to perform input validation using an
input mask
to define which characters are supported and where. This can be applied to the field as follows:It allow a series of 3-digit numbers separated with periods, and could therefore be used to validate
IPv4
addresses.widget.setInputMask('000.000.000.000;_')
QSpinBox and QDoubleSpinBox¶
QSpinBox
provides a small numerical input box with arrows to increase and decrease the value.QSpinBox
supportsintegers
while the related widgetQDoubleSpinBox
supportsfloats
.Example
- The value shows pre and post fix units, and is limited to the range +3 to -10.
- To set the range of acceptable values you can use
setMinimum
andsetMaximum
, or alternatively usesetRange
to set both simultaneously.
class MainWindow(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle("My App") widget = QSpinBox() # Or: widget = QDoubleSpinBox() widget.setMinimum(-10) widget.setMaximum(3) # Or: widget.setRange(-10,3) widget.setPrefix("$") widget.setSuffix("c") widget.setSingleStep(3) # Or e.g. 0.5 for QDoubleSpinBox widget.valueChanged.connect(self.value_changed) widget.textChanged.connect(self.value_changed_str) self.setCentralWidget(widget) def value_changed(self, i): print(i) def value_changed_str(self, s): print(s)
Both
QSpinBox
andQDoubleSpinBox
have a.valueChanged
signal which fires whenever their value is altered.- The raw
.valueChanged
signal sends thenumeric
value (either an int or a float) .textChanged
sends the value as astring
, including both the prefix and suffix characters.
- The raw
You can optionally disable text input on the spin box line edit, by setting it to read-only. With this set, the value can only by changed using the controls
widget.lineEdit().setReadOnly(True)
QSlider¶
QPushButton
creates a clickable button. Here's how to create a QPushButton
:
There is an additional
.sliderMoved
signal
that is triggered whenever the slider moves positionand a .
sliderPressed
signal that emits whenever the slider is clicked.class MainWindow(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle("My App") widget = QSlider() widget.setMinimum(-10) widget.setMaximum(3) # Or: widget.setRange(-10,3) widget.setSingleStep(3) widget.valueChanged.connect(self.value_changed) widget.sliderMoved.connect(self.slider_position) widget.sliderPressed.connect(self.slider_pressed) widget.sliderReleased.connect(self.slider_released) self.setCentralWidget(widget) def value_changed(self, i): print(i) def slider_position(self, p): print("position", p) def slider_pressed(self): print("Pressed!") def slider_released(self): print("Released")
You can also construct a slider with a
vertical
orhorizontal
orientation by passing the orientation in as you create it. Theorientation flags
are defined in theQt. namespace
.widget = QSlider(Qt.Orientiation.Vertical) widget = QSlider(Qt.Orientiation.Horizontal)