Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Can I find the layout a given widget is a member of?



  • I have a QButton (which has a label that names the actual item) and a QCheckBox to enable/disable the item named (CheckBox only has Enable in it's text string).
    I thought the a solution to extract the name of the item (on click of the checkbox) might be if I add them into a QHBoxLayout. But turns out that layouts don't work as the parent of children. Is there another way, that I can find the layout of a particular item (in this case, I want to find the layout the QCheckBox is a member of)?
    Then I could easily find the button that's in the layout too with QLayout::itemAt() and extract its text. but I'm still missing to find the correct QLayout - any ideas and/or hints?



  • why do you care what layout a widget is in? there are plenty of inqury methods to determine what widget is in play:
    sender(),
    parent(),
    findChildren()
    children()

    but if you must get the layout then remember that a widget can only have one active layout and do

    QLayout* layout{dynamic_cast<QWidget*>(parent())->layout()};
    


  • I think I have a better idea of how to do this:
    I create my own class that features a
    QButton,a QCheckBox , a QHBoxLayout and a QString to name it (and set the button's caption) and two function pointers, one that's hooked up with the button click and the other one that's hooked up with the checkbox click.

    Is this a good way to solve this?



  • If I understand what you are trying to do, then yes, encapsulating the checkbox and button in a single class makes sense. the layout thing is totally irrelevant.

    So, you only want the button active if the checkbox is checked? is that the gist of what you are trying to do? If so then create the class and implement signals that can be sent from it when the button is pushed. the checkbox doesn't even have to be visible at the broader scope level then.



  • @kent-dorfman said in Can I find the layout a given widget is a member of?:

    If I understand what you are trying to do, then yes, encapsulating the checkbox and button in a single class makes sense. the layout thing is totally irrelevant.

    But that will nicely align the elements horizontally automatically (which is what I want) as I create an instance of my new class

    So, you only want the button active if the checkbox is checked? is that the gist of what you are trying to do?
    Correct

    If so then create the class and implement signals that can be sent from it when the button is pushed. the checkbox doesn't even have to be visible at the broader scope level then.

    Why not? I actually want to store and apply the setting to a different module as well, i.e. I need to know when the checkbox gets selected/cleared too... I'll have to play around a bit but I think I got the gist of how to get it done! :)


  • Moderators

    @cerr said in Can I find the layout a given widget is a member of?:

    I think I have a better idea of how to do this:
    I create my own class that features a
    QButton,a QCheckBox , a QHBoxLayout and a QString to name it (and set the button's caption) and two function pointers, one that's hooked up with the button click and the other one that's hooked up with the checkbox click.

    Is this a good way to solve this?

    By "function pointer", do you mean "signal"? If so, then yes.

    However, you don't need to store a QHBoxLayout or QString.

    Why not? I actually want to store and apply the setting to a different module as well, i.e. I need to know when the checkbox gets selected/cleared too

    @Kent-Dorfman is saying that your checkbox should be private inside your custom class; it should not be accessible to anyone outside your class. This is the concept of encapsulation in object-oriented programming.

    You can connect signals from the checkbox and button to your own custom signals, and you can add implement your own functions that operate on your inner widgets. You don't need to expose the inner widgets to the outside world.

    MyWidget : public QWidget
    {
        Q_OBJECT
    
    public:
        MyWidget(const QString &caption = "Click Me", QWidget *parent = nullptr) : QWidget(parent),
                checkBox(new QCheckBox("Enabled")),
                pushButton(new QPushButton(caption))
        {
            connect(checkBox, &QCheckBox::toggled,
                    button, &QPushButton::setEnabled);
            connect(checkBox, &QCheckBox::toggled,
                    this, &MyWidget::checkBoxToggled);
            connect(button, &PushButton::clicked,
                    this, &MyWidget::buttonClicked);
                    
            auto layout = new QHBoxLayout;
            layout->addWidget(checkBox);
            layout->addWidget(button);
            this->setLayout(layout);
        }
        
        QString caption() const { return button->text(); }
        void setCaption(const QString &caption) { button->setText(caption); }
        
        bool isChecked() const { return checkBox->isChecked(); }
        void setChecked(bool ch) { checkBox->setChecked(ch); }
        
    signals:
        void checkBoxToggled(bool) const;
        void buttonClicked() const;
        
    private:
        QCheckBox *checkBox;
        QPushButton *button;    
    };
    

Log in to reply