The QToolButton
widget in PySide6 offers a flexible and stylish way to create compact, icon-based controls in your Python GUI applications. Whether you’re building a toolbar, adding quick-access buttons, or designing toggleable options, mastering QToolButton
is a must for modern desktop interfaces.
In this post, you’ll explore 10 hands-on exercises designed to help you understand and implement key QToolButton
features. From setting icons and styles to creating pop-up menus and keyboard shortcuts, these beginner-friendly examples will guide you through real-world usage scenarios.
Whether you’re just starting with PySide6 or expanding your GUI toolkit, these exercises will help you write cleaner, smarter, and more interactive user interfaces with Python.
"""
Exercise 1: Basic Tool Button with Icon
Objective:
Create a simple QToolButton with an icon (e.g., "Open"). When clicked, print a message: "ToolButton clicked".
"""
import sys
from PySide6.QtWidgets import QApplication, QWidget, QToolBar, QVBoxLayout, QToolButton, QLabel
from PySide6.QtGui import QIcon, Qt
class BasicToolButton(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('Basic Tool Button with Icon')
self.setStyleSheet('background-color: white; font-size: 25px;')
self.resize(400, 300)
self.tool_button = QToolButton(self)
self.tool_button.setText('Open')
self.tool_button.setIcon(QIcon('play.png'))
self.tool_button.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)
self.tool_button.clicked.connect(self.on_tool_button_clicked)
self.label = QLabel(self)
main_layout = QVBoxLayout()
main_layout.addWidget(self.tool_button)
main_layout.addWidget(self.label)
self.setLayout(main_layout)
def on_tool_button_clicked(self):
self.label.setText('ToolButton Clicked.')
if __name__ == '__main__':
app = QApplication(sys.argv)
window = BasicToolButton()
window.show()
app.exec()
"""
Exercise 2: ToolButton with Text Below Icon
Objective:
Create a QToolButton with both an icon and a label.
Use ToolButtonTextUnderIcon style to display the text below the icon.
"""
import sys
from PySide6.QtWidgets import QToolButton, QApplication, QWidget, QVBoxLayout
from PySide6.QtGui import QIcon, Qt
class ToolButtonTextBelowIcon(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('ToolButton with Text Below Icon')
self.setStyleSheet('background-color: rgb(255, 255, 255); font-size: 25px;')
self.resize(300, 300)
self.tool_button = QToolButton(self)
self.tool_button.setText('This is a tool button')
self.tool_button.setIcon(QIcon('play.png'))
self.tool_button.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)
main_layout = QVBoxLayout()
main_layout.setAlignment(Qt.AlignCenter)
main_layout.addWidget(self.tool_button)
self.setLayout(main_layout)
if __name__ == '__main__':
app = QApplication(sys.argv)
window = ToolButtonTextBelowIcon()
window.show()
app.exec()
"""
Exercise 3: Toggleable ToolButton
Objective:
Make a QToolButton checkable. When toggled, change its background color using setStyleSheet() based on checked state.
"""
import sys
from PySide6.QtWidgets import QToolButton, QWidget, QApplication, QVBoxLayout
from PySide6.QtGui import QIcon
from PySide6.QtCore import Qt
class ToggleableToolButton(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('Toggleable ToolButton')
self.setStyleSheet('background-color: rgb(255, 255, 255); font-size: 25px;')
self.resize(200, 200)
self.tool_button = QToolButton(self)
self.tool_button.setStyleSheet('background-color: red; font-size: 25px; color: white')
self.tool_button.setText('Red Background')
self.tool_button.setIcon(QIcon('play.png'))
self.tool_button.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)
self.tool_button.setCheckable(True)
self.tool_button.toggled.connect(self.change_background)
main_layout = QVBoxLayout()
main_layout.setAlignment(Qt.AlignCenter)
main_layout.addWidget(self.tool_button)
self.setLayout(main_layout)
def change_background(self, checked):
if checked:
self.tool_button.setStyleSheet('background-color: green; color: white; font-size: 25px')
else:
self.tool_button.setStyleSheet('background-color: red; color: white; font-size: 25px')
if __name__ == '__main__':
app = QApplication(sys.argv)
window = ToggleableToolButton()
window.show()
app.exec()
"""
Exercise 4: ToolButton Popup Menu
Objective:
Create a QToolButton with a dropdown QMenu. Set popup mode to MenuButtonPopup.
Menu items should print their label when selected.
"""
import sys
from PySide6.QtWidgets import QMenu, QApplication, QWidget, QVBoxLayout, QToolButton
from PySide6.QtGui import QAction, QIcon
from PySide6.QtCore import Qt
class ToolButtonPopupMenu(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("Popup Menu")
self.setStyleSheet("QToolButton {background-color:white; font-size: 25pt;}")
self.resize(400, 300)
self.tool_button = QToolButton(self)
self.tool_button.setText('Options')
self.tool_button.setIcon(QIcon('play.png'))
self.tool_button.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)
self.tool_button.setPopupMode(QToolButton.MenuButtonPopup)
self.menu = QMenu()
actions = ['Open', 'Save', 'Exit']
for action_name in actions:
action = QAction(action_name, self)
action.triggered.connect(lambda checked, name=action_name: self.menu_item_selected(name))
self.menu.addAction(action)
self.tool_button.setMenu(self.menu)
main_layout = QVBoxLayout()
main_layout.addWidget(self.tool_button)
main_layout.setAlignment(Qt.AlignCenter)
self.setLayout(main_layout)
def menu_item_selected(self, item_name):
print(f'Menu item selected: {item_name}')
if __name__ == '__main__':
app = QApplication(sys.argv)
window = ToolButtonPopupMenu()
window.show()
app.exec()
"""
Exercise 5: ToolButton as Toolbar Shortcut
Objective:
Create a horizontal layout of three QToolButtons (e.g., Cut, Copy, Paste).
Assign icons and connect them to different actions.
"""
import sys
from PySide6.QtWidgets import QApplication, QWidget, QToolButton, QHBoxLayout, QVBoxLayout
from PySide6.QtGui import QIcon
from PySide6.QtCore import Qt, QSize
class ToolButtonAsToolbarShortcut(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("Tool Button As Toolbar Shortcut")
self.setStyleSheet('font-size: 25px;')
self.resize(400, 300)
icons_list = ['Cut', 'Copy', 'Paste']
layout_button = QHBoxLayout()
for icon_name in icons_list:
self.button = QToolButton()
self.button.setFixedWidth(150)
self.button.setText(f'{icon_name}')
self.button.setIconSize(QSize(25, 25))
self.button.setIcon(QIcon(f'{icon_name}.png'))
self.button.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)
if icon_name == 'Cut':
self.button.clicked.connect(self.cut_action)
elif icon_name == 'Copy':
self.button.clicked.connect(self.copy_action)
elif icon_name == 'Paste':
self.button.clicked.connect(self.paste_action)
layout_button.addWidget(self.button)
main_layout = QVBoxLayout()
main_layout.addLayout(layout_button)
self.setLayout(main_layout)
def cut_action(self):
print('Cut')
def copy_action(self):
print('Copy')
def paste_action(self):
print('Paste')
if __name__ == '__main__':
app = QApplication(sys.argv)
window = ToolButtonAsToolbarShortcut()
window.show()
app.exec()
"""
Exercise 6: ToolButton Icon Size Control
Objective:
Create a QToolButton with a large icon (e.g., 48x48 px). Use .setIconSize() to resize the icon and observe the change.
"""
import sys
from PySide6.QtCore import QSize, Qt
from PySide6.QtGui import QIcon
from PySide6.QtWidgets import QToolButton, QApplication, QWidget, QVBoxLayout
class ToolButtonIconSizeControl(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('ToolButton Icon Size Control')
self.setStyleSheet('font-size: 25px')
self.resize(400, 400)
self.tool_button = QToolButton(self)
self.tool_button.setIcon(QIcon('sentiment_satisfied_24dp_1F1F1F_FILL0_wght400_GRAD0_opsz24.png'))
self.tool_button.setIconSize(QSize(48, 48))
self.tool_button.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)
self.tool_button.setToolTip('Icon Size Control')
self.tool_button.setText('Icon Size Control')
self.tool_button.clicked.connect(self.change_size)
main_layout = QVBoxLayout()
main_layout.addWidget(self.tool_button)
self.setLayout(main_layout)
def change_size(self):
self.tool_button.setIconSize(QSize(100, 100))
if __name__ == '__main__':
app = QApplication(sys.argv)
window = ToolButtonIconSizeControl()
window.show()
app.exec()
"""
Exercise 7: Disable/Enable ToolButton
Objective:
Create a checkbox and a QToolButton. Toggling the checkbox enables/disables the button.
"""
import sys
from PySide6.QtGui import QIcon
from PySide6.QtCore import Qt, QSize
from PySide6.QtWidgets import QToolButton, QCheckBox, QApplication, QWidget, QVBoxLayout
class DisableEnableToolButton(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('Disable/Enable ToolButton')
self.setStyleSheet('font-size: 25px')
self.resize(400, 400)
self.tool_button = QToolButton(self)
self.tool_button.setText('Not functioning')
self.tool_button.setIcon(QIcon('toggle_off_24dp_1F1F1F_FILL0_wght400_GRAD0_opsz24.png'))
self.tool_button.setIconSize(QSize(50, 50))
self.tool_button.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)
self.tool_button.setEnabled(False)
self.checkbox = QCheckBox('Enable/Disable ToolButton')
self.checkbox.setStyleSheet('font-size: 14px')
self.checkbox.toggled.connect(self.enable_disable)
main_layout = QVBoxLayout()
main_layout.addWidget(self.checkbox)
main_layout.addWidget(self.tool_button)
self.setLayout(main_layout)
def enable_disable(self):
if self.checkbox.isChecked():
self.tool_button.setEnabled(True)
self.tool_button.setText('Functioning')
self.tool_button.setIcon(QIcon('toggle_on_24dp_1F1F1F_FILL0_wght400_GRAD0_opsz24.png'))
else:
self.tool_button.setEnabled(False)
self.tool_button.setText('Not functioning')
self.tool_button.setIcon(QIcon('toggle_off_24dp_1F1F1F_FILL0_wght400_GRAD0_opsz24.png'))
if __name__ == '__main__':
app = QApplication(sys.argv)
window = DisableEnableToolButton()
window.show()
app.exec()
"""
Exercise 8: ToolButton Tooltip and Shortcut
Objective:
Assign a tooltip and keyboard shortcut (e.g., Ctrl+T) to a QToolButton.
When triggered by mouse or keyboard, print "Activated!".
"""
import sys
from PySide6.QtWidgets import QToolButton, QApplication, QWidget, QVBoxLayout
from PySide6.QtGui import QIcon, QShortcut, QKeySequence
from PySide6.QtCore import Qt
class ToolButtonToolTipShortcut(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("ToolButton Shortcut")
self.setStyleSheet('font-size: 25px')
self.resize(400, 300)
self.tool_button = QToolButton(self)
self.tool_button.setText("Trigger")
self.tool_button.setIcon(QIcon("play.png"))
self.tool_button.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)
self.tool_button.setToolTip("Click or Press CTRL+T to Activate")
self.tool_button.clicked.connect(self.activate_button)
shortcut = QShortcut(QKeySequence("Ctrl+T"), self)
shortcut.activated.connect(self.activate_button)
main_layout = QVBoxLayout()
main_layout.addWidget(self.tool_button)
main_layout.setAlignment(Qt.AlignCenter)
self.setLayout(main_layout)
def activate_button(self):
print("Activated!")
if __name__ == "__main__":
app = QApplication(sys.argv)
window = ToolButtonToolTipShortcut()
window.show()
app.exec()
"""
Exercise 9: ToolButton with Flat Style
Objective:
Create a QToolButton with .setAutoRaise(True) to make it flat (like a modern toolbar).
Use hover effects via setStyleSheet().
"""
import sys
from PySide6.QtWidgets import QToolButton, QApplication, QWidget, QVBoxLayout
from PySide6.QtGui import QIcon
from PySide6.QtCore import Qt, QSize
class ToolButtonFlatStyle(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('ToolButton Flat Style')
self.setStyleSheet('font-size: 25px;')
self.resize(400, 300)
self.tool_button = QToolButton(self)
self.tool_button.setAutoRaise(True)
self.tool_button.setIcon(QIcon('sentiment_satisfied_24dp_1F1F1F_FILL0_wght400_GRAD0_opsz24.png'))
self.tool_button.setIconSize(QSize(50, 50))
self.tool_button.setStyleSheet('''
QToolButton
{
border: none;
padding: 10px;
}
QToolButton:hover
{
background-color: rgb(255, 255, 255);
border-radius: 5px;
}
''')
main_layout = QVBoxLayout()
main_layout.addWidget(self.tool_button)
self.setLayout(main_layout)
if __name__ == '__main__':
app = QApplication(sys.argv)
window = ToolButtonFlatStyle()
window.show()
app.exec()
"""
Exercise 10: ToolButton Acting as Radio Buttons
Objective:
Create three toggleable QToolButtons ("Small", "Medium", "Large").
Use QButtonGroup to allow only one to be active at a time. Display the selected size in a QLabel.
"""
import sys
from PySide6.QtWidgets import QApplication, QWidget, QToolButton, QHBoxLayout, QLabel, QButtonGroup
from PySide6.QtGui import QIcon
from PySide6.QtCore import Qt, QSize
class ToolButtonAsRadioButton(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("ToolButton Acting as Radio Buttons")
self.setStyleSheet('font-size: 25px')
self.resize(400, 400)
self.tool_button_small = QToolButton(self)
self.tool_button_small.setText("Small")
self.tool_button_small.setCheckable(True)
self.tool_button_small.setIcon(QIcon('photo_size_select_small_24dp_1F1F1F_FILL0_wght400_GRAD0_opsz24.png'))
self.tool_button_small.setIconSize(QSize(50, 50))
self.tool_button_medium = QToolButton(self)
self.tool_button_medium.setText("Medium")
self.tool_button_medium.setCheckable(True)
self.tool_button_medium.setIcon(QIcon('picture_in_picture_medium_24dp_1F1F1F_FILL0_wght400_GRAD0_opsz24.png'))
self.tool_button_medium.setIconSize(QSize(50, 50))
self.tool_button_large = QToolButton(self)
self.tool_button_large.setText("Large")
self.tool_button_large.setCheckable(True)
self.tool_button_large.setIcon(QIcon('photo_size_select_large_24dp_1F1F1F_FILL0_wght400_GRAD0_opsz24.png'))
self.tool_button_large.setIconSize(QSize(50, 50))
self.tool_button_group = QButtonGroup(self)
self.tool_button_group.setExclusive(True)
self.tool_button_group.addButton(self.tool_button_small)
self.tool_button_group.addButton(self.tool_button_medium)
self.tool_button_group.addButton(self.tool_button_large)
self.tool_button_group.buttonClicked.connect(self.activate_button)
self.label = QLabel(self)
main_layout = QHBoxLayout()
main_layout.addWidget(self.tool_button_small)
main_layout.addWidget(self.tool_button_medium)
main_layout.addWidget(self.tool_button_large)
main_layout.addWidget(self.label)
self.setLayout(main_layout)
def activate_button(self, button):
self.label.setText(f'{button.text()} is active')
if __name__ == '__main__':
app = QApplication(sys.argv)
window = ToolButtonAsRadioButton()
window.show()
app.exec()