For many years, I have used a small class called ShootABug. This is used to debug parts of the user interface of Qt applications.

I don’t know who originally wrote this. It’s been floating around the Qt and KDE people for more than ten years. But it’s still one of the most useful little tools for one particular problem: “What is that thing in my GUI?”

There is another type of problem this is really good at fixing: When your layouts start misbehaving, and you get odd areas of space where there shouldn’t be. Installing ShootABug will tell you which widget has this space, so you can find the bad layout. AFAIK, this is pretty much the only realistic way of debugging layouts in Qt.

ShootABug is an event filter. When you click in the GUI, it will tell you what widget you have clicked on. Or whatever information you ask it to give.

Add it to your application with this piece of code:

qApp->installEventFilter(new ShootABug());

Here is the code for the class itself:

class ShootABug : public QObject {
public:
    virtual bool eventFilter(QObject* receiver, QEvent* ev) {
        if (ev->type() != QEvent::MouseButtonPress)
            return false;
        QMouseEvent* event = static_cast<QMouseEvent*>(ev);
        if (event->modifiers() != Qt::ControlModifier)
            return false;
        qDebug() << receiver->objectName()
            << receiver->metaObject()->className();
        // Print other useful information here
        // Return false, if you want the application to receive the event
        return false;
    }
};

When you hold down ctrl and press the mouse somewhere in your application, you will see some debug output describing the widget you have pressed. Useful information to write is of course the object name and class name. Object tree, child list or parent are other things sometimes worth adding.

When you are working with your GUI and hit a problem, you should activate ShootABug, fix the problem and deactivate it again. Don’t check code in to your repository with ShootABug installed. Especially not if you eat the event by returning true from your event filter. But even if you don’t do this, it’s a bad idea to have ShootABug installed all the time. You will forget it’s there, and there is a significant performance hit from it.