2020-04-16

Little surprises #2: Qt Designer tricks

Constant-correctness in C++ is not something that you can practically do half-way. You either do it everywhere and always or you don't do it unless some library you're interfacing with forces your hand. I'm in the former camp, and I think that this is a choice with right and wrong answers. Doing it is right.

As a result I've gotten into the habit of typing const after method signatures almost without thinking, so that sometimes the linter has to remind me that I'm changing a object's state in a method marked as constant. In doing so I recently stumbled on a oddity of Qt's Designer tool.

There is a difference between having something and knowing where to find it


The interesting thing about the Designer component of Qt Creator is that it generates code of a separate UI object (which you are expected to not edit) and a skeleton widget object for you to flesh out. That skeleton includes a pointer-member to manage the UI object (and of course, Designer generates the requisite c'tor and d'tor behavior to make that safe).

If I use Qt Creator to generate a minimal QWidget the header file it writes looks like this:
#ifndef FORM_H
#define FORM_H

#include 

namespace Ui {
class Form;
}

class Form : public QWidget
{
    Q_OBJECT

public:
    explicit Form(QWidget *parent = nullptr);
    ~Form();

private:
    Ui::Form *ui;
};

#endif // FORM_H

If I write a method for this class From::changeSubWidget(QWidget*) const, I won't be able to change the pointer this->ui, but I will be able to change the properties of any subwidgets contained in the UI::Form object at the other end of the pointer..

Of course this has nothing to do with Designer per se and everything to do with the having a pointer or reference member. More over there are places where this is definitely a feature rather than a bug.

Philosophy


In my personal universe a method of the widget class that changes the UI should not be marked const even if the particular implementation you've chosen (or let the designer chose) allows it. Because (a) it's not really sensible (the widget that the user sees on their screen is changing) and (b) it locks you into a group of implementation stratigies (you can't later decide to pull all those UI elements into your class proper, which is admittedly not a big issue in Qt).

No comments:

Post a Comment