How to Center Icons in a QListWidget

Displaying icons centered in QListWidget items using PyQt6 or PySide6
Heads up! You've already completed this tutorial.

I can center text in a QListWidget using setTextAlignment(Qt.AlignCenter), but how do I center the icons as well?

When you're working with QListWidget and adding items that have both icons and text, you'll notice that setTextAlignment only affects the text. The icon stays stubbornly left-aligned. So how do you get the icon to sit nicely in the center of the item?

The answer depends on which view mode your QListWidget is using. Let's walk through the options.

Understanding QListWidget View Modes

By default, QListWidget uses list mode (QListView.ViewMode.ListMode). In list mode, each item is displayed as a row, with the icon on the left and text to its right. The icon position in this mode is fixed — it always appears to the left of the text, and there's no built-in alignment property to change that.

If you want icons to appear centered within each item, the most straightforward approach is to switch to icon mode (QListView.ViewMode.IconMode). In icon mode, each item is displayed as a block with the icon above the text, and both can be centered.

Centering Icons with Icon Mode

Here's a minimal working example that creates a QListWidget in icon mode, with centered icons and text:

python
import sys

from PyQt6.QtCore import QSize, Qt
from PyQt6.QtGui import QIcon
from PyQt6.QtWidgets import (
    QApplication,
    QListWidget,
    QListWidgetItem,
    QMainWindow,
)


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Centered Icons in QListWidget")

        self.list_widget = QListWidget()

        # Switch to icon mode — icons appear above text, centered.
        self.list_widget.setViewMode(QListWidget.ViewMode.IconMode)

        # Set the icon size for the widget.
        self.list_widget.setIconSize(QSize(48, 48))

        # Optional: prevent items from being dragged around.
        self.list_widget.setMovement(QListWidget.Movement.Static)

        # Add some items.
        for label in ["Open", "Save", "Print", "Close"]:
            item = QListWidgetItem(QIcon("icon.png"), label)
            item.setTextAlignment(Qt.AlignmentFlag.AlignCenter)
            item.setSizeHint(QSize(80, 80))
            item.setFlags(
                Qt.ItemFlag.ItemIsSelectable | Qt.ItemFlag.ItemIsEnabled
            )
            self.list_widget.addItem(item)

        self.setCentralWidget(self.list_widget)


app = QApplication(sys.argv)
window = MainWindow()
window.resize(400, 200)
window.show()
app.exec()

Replace "icon.png" with the path to any icon file you have available. Each item will display the icon centered above the text. If you need help loading images and icons in your application, see adding images to PyQt6 applications.

A few things to note in this example:

  • setViewMode(QListWidget.ViewMode.IconMode) arranges items in a grid with the icon above the text. Both are naturally centered within the item's area.
  • setIconSize(QSize(48, 48)) controls how large the icons are drawn. Without this, icons may appear at their native size, which can look inconsistent.
  • setSizeHint(QSize(80, 80)) on each item tells the widget how much space to allocate per item. Make sure this is large enough to fit both the icon and the text.
  • setMovement(QListWidget.Movement.Static) prevents users from dragging items around. In icon mode, items are draggable by default, which is often not what you want.

What If You Need List Mode?

If you need to keep the standard list layout (one item per row, scrolling vertically), icons will always sit to the left of the text. That's how QListView renders items in list mode — the icon and text share a single row, and the icon position isn't adjustable through item properties alone.

In that situation, you have two options:

Use a Custom Delegate

You can subclass QStyledItemDelegate and override its paint method to draw the icon wherever you like. This gives you full control over how each item is rendered, but it requires more code.

Here's a basic example of a delegate that draws the icon centered above the text, while still keeping the list in list mode:

python
import sys

from PyQt6.QtCore import QRect, QSize, Qt
from PyQt6.QtGui import QIcon
from PyQt6.QtWidgets import (
    QApplication,
    QListWidget,
    QListWidgetItem,
    QMainWindow,
    QStyle,
    QStyledItemDelegate,
)


class CenteredIconDelegate(QStyledItemDelegate):
    def paint(self, painter, option, index):
        # Draw the background and selection highlight.
        self.initStyleOption(option, index)
        style = option.widget.style() if option.widget else QApplication.style()
        style.drawPrimitive(
            QStyle.PrimitiveElement.PE_PanelItemViewItem,
            option,
            painter,
            option.widget,
        )

        painter.save()

        icon = index.data(Qt.ItemDataRole.DecorationRole)
        text = index.data(Qt.ItemDataRole.DisplayRole)

        icon_size = option.decorationSize
        rect = option.rect

        # Draw the icon centered horizontally at the top of the item.
        if icon and not icon.isNull():
            icon_x = rect.x() + (rect.width() - icon_size.width()) // 2
            icon_y = rect.y() + 4
            icon_rect = QRect(
                icon_x, icon_y, icon_size.width(), icon_size.height()
            )
            icon.paint(painter, icon_rect)

        # Draw the text centered below the icon.
        if text:
            text_y = rect.y() + icon_size.height() + 8
            text_rect = QRect(
                rect.x(),
                text_y,
                rect.width(),
                rect.height() - icon_size.height() - 8,
            )
            painter.drawText(
                text_rect,
                Qt.AlignmentFlag.AlignHCenter | Qt.AlignmentFlag.AlignTop,
                text,
            )

        painter.restore()

    def sizeHint(self, option, index):
        return QSize(option.rect.width(), 80)


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Centered Icons with Delegate")

        self.list_widget = QListWidget()
        self.list_widget.setIconSize(QSize(32, 32))
        self.list_widget.setItemDelegate(
            CenteredIconDelegate(self.list_widget)
        )

        for label in ["Open", "Save", "Print", "Close"]:
            item = QListWidgetItem(QIcon("icon.png"), label)
            item.setSizeHint(QSize(0, 80))
            self.list_widget.addItem(item)

        self.setCentralWidget(self.list_widget)


app = QApplication(sys.argv)
window = MainWindow()
window.resize(300, 400)
window.show()
app.exec()

This keeps the vertical list layout but renders each item with a centered icon above the text.

Embed a Custom Widget in Each Item

Another approach is to use QListWidget.setItemWidget() to place a custom widget (for example, a QWidget with a QVBoxLayout containing a QLabel for the icon and another for the text) inside each item. This is flexible but heavier — each item gets its own widget hierarchy, which can be slower with many items. For more on building your own custom widgets, see the creating custom widgets tutorial.

For most cases, either switching to icon mode or using a custom delegate will give you the result you're looking for.

Summary

  • Icon mode (setViewMode(QListWidget.ViewMode.IconMode)) is the simplest way to get centered icons. Items display with the icon above the text, both centered.
  • setTextAlignment(Qt.AlignmentFlag.AlignCenter) centers text but has no effect on icon positioning.
  • setIconSize() on the QListWidget controls how large icons are drawn — always set this explicitly.
  • For centered icons in list mode, use a custom QStyledItemDelegate to take control of how items are painted.

If you're just getting started with PyQt6, take a look at the basic widgets overview to familiarize yourself with the standard widget types available, or learn more about layouts to arrange widgets effectively in your applications.

Well done, you've finished this tutorial! Mark As Complete
[[ user.completed.length ]] completed [[ user.streak+1 ]] day streak

Create GUI Applications with Python & Qt6 by Martin Fitzpatrick

(PySide6 Edition) The hands-on guide to making apps with Python — Over 15,000 copies sold!

More info Get the book

Martin Fitzpatrick

How to Center Icons in a QListWidget was written by Martin Fitzpatrick.

Martin Fitzpatrick has been developing Python/Qt apps for 8 years. Building desktop applications to make data-analysis tools more user-friendly, Python was the obvious choice. Starting with Tk, later moving to wxWidgets and finally adopting PyQt. Martin founded PythonGUIs to provide easy to follow GUI programming tutorials to the Python community. He has written a number of popular Python books on the subject.