In this guide, you'll learn how to create a custom ColorButton widget in PyQt5 and PySide2 — a color-picker button that opens a native QColorDialog when clicked and displays the selected color on the button face.
This reusable custom widget is perfect for settings panels, drawing applications, or any Python GUI where users need to pick a color.
How the ColorButton Widget Works
Clicking on the button pops up a native color dialog to select a color. The currently selected color is shown as the background color of the button. You can provide a default color which will be the initial state of the button when it is created — right-clicking on the button will reset the color to this default value (or None if no default is set).
To get the currently set color, use button.color(). The widget also emits a colorChanged signal whenever the selected color changes, making it easy to connect to other parts of your application.
Custom ColorButton Widget Code
Below is the complete implementation of the custom ColorButton widget for both PyQt5 and PySide2. You can copy this directly into your project or adapt it to your needs.
- PyQt5
- PySide
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import Qt, pyqtSignal
class ColorButton(QtWidgets.QPushButton):
'''
Custom Qt Widget to show a chosen color.
Left-clicking the button shows the color-chooser, while
right-clicking resets the color to None (no-color).
'''
colorChanged = pyqtSignal(object)
def __init__(self, *args, color=None, **kwargs):
super().__init__(*args, **kwargs)
self._color = None
self._default = color
self.pressed.connect(self.onColorPicker)
# Set the initial/default state.
self.setColor(self._default)
def setColor(self, color):
if color != self._color:
self._color = color
self.colorChanged.emit(color)
if self._color:
self.setStyleSheet("background-color: %s;" % self._color)
else:
self.setStyleSheet("")
def color(self):
return self._color
def onColorPicker(self):
'''
Show color-picker dialog to select color.
Qt will use the native dialog by default.
'''
dlg = QtWidgets.QColorDialog(self)
if self._color:
dlg.setCurrentColor(QtGui.QColor(self._color))
if dlg.exec_():
self.setColor(dlg.currentColor().name())
def mousePressEvent(self, e):
if e.button() == Qt.RightButton:
self.setColor(self._default)
return super().mousePressEvent(e)
from PySide2 import QtCore, QtGui, QtWidgets
from PySide2.QtCore import Qt, Signal
class ColorButton(QtWidgets.QPushButton):
'''
Custom Qt Widget to show a chosen color.
Left-clicking the button shows the color-chooser, while
right-clicking resets the color to None (no-color).
'''
colorChanged = Signal(object)
def __init__(self, *args, color=None, **kwargs):
super().__init__(*args, **kwargs)
self._color = None
self._default = color
self.pressed.connect(self.onColorPicker)
# Set the initial/default state.
self.setColor(self._default)
def setColor(self, color):
if color != self._color:
self._color = color
self.colorChanged.emit(color)
if self._color:
self.setStyleSheet("background-color: %s;" % self._color)
else:
self.setStyleSheet("")
def color(self):
return self._color
def onColorPicker(self):
'''
Show color-picker dialog to select color.
Qt will use the native dialog by default.
'''
dlg = QtWidgets.QColorDialog(self)
if self._color:
dlg.setCurrentColor(QtGui.QColor(self._color))
if dlg.exec_():
self.setColor(dlg.currentColor().name())
def mousePressEvent(self, e):
if e.button() == Qt.RightButton:
self.setColor(self._default)
return super().mousePressEvent(e)
How to Use the ColorButton in Your Application
To add the ColorButton to your PyQt5 or PySide2 application, create an instance and add it to your layout like any other widget:
button = ColorButton(color="#ff0000") # Start with red as default
button.colorChanged.connect(lambda color: print("Selected color:", color))
layout.addWidget(button)
Left-click the button to open the color picker dialog. Right-click to reset the color back to the default.
Key Features
- Native color dialog — Uses
QColorDialogwhich displays the platform-native color picker on supported systems. - Visual feedback — The button background updates to reflect the currently selected color using
setStyleSheet. - Default color support — Pass a default color on initialization and right-click to reset back to it at any time.
- Custom signal support — The
colorChangedsignal is emitted whenever the color changes, allowing easy integration with your PyQt5 or PySide2 application.
This custom widget is also available in the LearnPyQt qtwidgets library.
Packaging Python Applications with PyInstaller by Martin Fitzpatrick
This step-by-step guide walks you through packaging your own Python applications from simple examples to complete installers and signed executables.