Creating Custom Widget for QListWidget in Qt 6

With the arrival of Qt 6 and the complete integration of CMake, I wanted to give Qt another try before I give up and go to Electron. So far it has been good.

I have been trying to create an app that uses QListWidget with custom widgets as a list, to list recently viewed files. The custom widget contains a label and a button, this button deletes itself on clicking. I had trouble connecting the child widget to the parent, and if you had the same problem then this article could help you.

The code can be found at https://github.com/akshaybabloo/qlistwidget-custom-widget

Some Basics

Let’s look at some basics before we dive into the project. If you are OK with the basics, move to the fun part.

Qt (read as cute) is a cross platform UI development platform that formally supports C++, Python and Qt QML programming languages.

Although Qt can be used by anyone, the company does have a stricter licencing program. If you are using the open-source version of Qt, you need to adhere to LGPL/GPL restrictions. Which basically means your source code should be open for others to view.

So, when choosing Qt as your next UI framework, make sure you know the licencing restriction.

Signals & Slots are one of the key features in Qt that allows two objects to communicate without importing them into your class. We will look at how to use this in our code.

Speed and performance. That is literally the only reason you want to use Qt. If that’s something you are not bothered with, I would recommend using Electron or JavaFX. See their website for more information.

Project Structure

Make sure you have installed the latest version of Qt 6. At the time of writing this article, I had Qt 6.0 installed. You can either use Qt Creator or CLion, both works great.

qlistwidget-custom-widget
├── CMakeLists.txt
├── customwidget.cpp
├── customwidget.h
├── customwidget.ui
├── main.cpp
├── mainwindow.cpp
├── mainwindow.h
└── mainwindow.ui

Main Windows

Let’s create a simple MainWindow class without a status bar and with all its margins & spacing set to `0`. To this window, drag and drop the `List Widget` from the left pane.

mainwindow.ui

This should look similar to the image below on macOS with dark mode enabled.

Main window with empty QListWidget.
Main window with empty QListWidget.
Main window with empty QListWidget.

Custom Widget

Create a new widget UI with class CustomWidget. Add a button and a label to it from the left pane.

customwidget.ui

This should look similar to the image below on macOS with dark mode enabled.

Widget with button, label and a horizontal spacer.
Widget with button, label and a horizontal spacer.
Widget with button, label, and a horizontal spacer.

Let’s Code

Let’s get into the fun part of this article — coding. Our `main.cpp` calls `MainWindow` object from `mainwindow.h`, which is the parent window. Let’s ignore `main.cpp` because we are not going to make any changes to it.

See customwidget.cpp and customwidget.h.

To the generated code, lets add two public methods — QString getText(), void setText(const QString &text) — one signal method — void sendRemoveItem(const QString &text) — and one slot method — void on_toolButton_clicked().

This method sets the text of the QLabel in the UI, whose name is given as label.

This method is a signal that is used to `emit` a signal to an objects Slot.

This is a slot method that reacts to the button — x — click on the UI. When the button is clicked, we can use `emit` to send the text to the required method.

We will come back to this method once we write the remaining methods in mainwindow.h

mainwindow.cpp and mainwindow.h

See mainwindow.cpp and mainwindow.h.

mainwindow.cpp and mainwindow.h are the entry points for UI, so we have to assign the CustomWindow object to QListWidget whose name in UI is listWidget. In this object we need to add some code to the constructor that creates new widgets and a private slot method — void removeItem(const QString &text) that receives a remove signal.

First import the custom widget — #include “customwidget.h”

In the MainWindow constructor add in the following code:

The &text is the QLabel text assigned to each instance of the widget while creating it. When the x button is clicked, the text is emitted to this method.

The above code matches the text and deletes the item from the listWidget.

Connecting CustomWidget to MainWindow

Remember we spoke about [Slots & Signals](#what-is-signals-and-slots), this is where we use that concept to connect `CustomWidget` object to `MainWindow` object.

In the constructor of `CustomWidget` write in the following code:

What we are saying here is — connect current class (CustomWidget) whose object is sendRemoveItem to the parent (MainWindow) whose object is removeItem()

Run the Application (GIF)

Once you run the application you should be able to delete any item from the list:

Application demo.
Application demo.
Application demo.

Conclusion

This article might be overwhelming, but there are only few parts of the code that actually matter — creating the UI, using the UI components, and connecting them together — rest are automatically generated by the Qt Creator. If you happen to come across a better alternative, please do comment below.

Happy coding! :)

PhD student, currently doing research on Spiking Neural Networks and Brain Computer Interfaces

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store