My canvas is not clearing every time I run my painting app, and on Windows the background appears black instead of white. How do I properly clear or fill the canvas when using QPainter and QPixmap in PyQt6?
If you've been following along with QPainter tutorials and find that your canvas has a black background — or that previous drawings aren't being cleared properly — you're running into one of the most common gotchas when working with QPixmap in PyQt6, especially on Windows.
The good news is that the fix is simple: you just need to explicitly fill your QPixmap with a color when you create it.
Why does the canvas appear black?
When you create a new QPixmap, the pixel data it contains is uninitialized. On some platforms (particularly Windows), this uninitialized data shows up as solid black. On other platforms, you might see random garbage pixels or a transparent background. The behavior is unpredictable because you're looking at whatever happened to be in that block of memory.
The solution is to fill the pixmap with your desired background color right after creating it.
Filling the canvas with a background color
Here's how to create a QPixmap and fill it with white:
from PyQt6 import QtGui
canvas = QtGui.QPixmap(400, 300)
canvas.fill(QtGui.QColor("#ffffff")) # Fill entire canvas with white.
The fill() method sets every pixel in the pixmap to the color you specify. By calling it immediately after creating the pixmap, you ensure a clean, predictable background before you start drawing anything.
You can use any color you like — #ffffff for white, Qt.GlobalColor.white, or any QColor value.
A complete working example
Here's a full example that creates a small painting application. The canvas starts with a white background, and you can click buttons to draw shapes on it. Notice how canvas.fill() is called right after the QPixmap is created.
import sys
from PyQt6 import QtCore, QtGui, QtWidgets
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self.canvas = QtGui.QPixmap(400, 300)
self.canvas.fill(QtGui.QColor("#ffffff")) # Start with a white canvas.
self.label = QtWidgets.QLabel()
self.label.setPixmap(self.canvas)
button_draw = QtWidgets.QPushButton("Draw Rectangle")
button_draw.clicked.connect(self.draw_rectangle)
button_clear = QtWidgets.QPushButton("Clear Canvas")
button_clear.clicked.connect(self.clear_canvas)
layout = QtWidgets.QVBoxLayout()
layout.addWidget(self.label)
layout.addWidget(button_draw)
layout.addWidget(button_clear)
container = QtWidgets.QWidget()
container.setLayout(layout)
self.setCentralWidget(container)
def draw_rectangle(self):
painter = QtGui.QPainter(self.canvas)
pen = QtGui.QPen()
pen.setWidth(3)
pen.setColor(QtGui.QColor("#333333"))
painter.setPen(pen)
painter.drawRect(50, 50, 200, 150)
painter.end()
self.label.setPixmap(self.canvas)
def clear_canvas(self):
self.canvas.fill(QtGui.QColor("#ffffff")) # Reset to white.
self.label.setPixmap(self.canvas)
app = QtWidgets.QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec()
Copy and run this to see it in action. Click "Draw Rectangle" to paint a shape, then click "Clear Canvas" to reset everything back to white. If you're new to building PyQt6 applications, see creating your first window for a beginner-friendly introduction.
How clearing works
The clear_canvas method does the same thing we did during initialization — it calls self.canvas.fill() to overwrite every pixel with white, then updates the QLabel by calling setPixmap() again. That's all there is to it. You don't need to call self.update() or any other manual refresh method when you're displaying your pixmap through a QLabel, because setPixmap() already triggers a repaint of the label widget.
When do you need self.update()?
If you're painting directly in a widget's paintEvent method (rather than painting onto a QPixmap displayed in a QLabel), then you would need to call self.update() to schedule a repaint after changing your drawing data. This approach is common when creating your own custom widgets. But when you're working with a QPixmap and a QLabel as shown above, calling setPixmap() handles the display update for you.
Summary
Whenever you create a QPixmap to use as a drawing canvas:
- Call
canvas.fill()immediately after creation to set a known background color. - To clear the canvas later, call
canvas.fill()again with your background color. - After modifying the pixmap, call
label.setPixmap(canvas)to update the display.
This approach works reliably across all platforms and avoids the black background issue entirely. For more advanced drawing techniques, including working with QPainter paths and shapes, check out the QPainter and bitmap graphics tutorial.
Create GUI Applications with Python & Qt6 by Martin Fitzpatrick
(PyQt6 Edition) The hands-on guide to making apps with Python — Over 15,000 copies sold!