How to set visibility on widgets within a subclass of QWidgetAction



  • I have a selection of classes derived from QWidgetAction. The QWidgetActions are all parented from a menu, and the widgets they contain are parented from the same menu. The contained widgets are all set as the default widget for the QWidgetAction. Nothing has been reimplemented from QWidgetAction. Each action is used only once.

    I thought that setting the visibility of the QWidgetAction would automatically set the visibility of the custom widget set contained within? Is this not true, as doing so is certainly not showing and hiding the widgets as required!? Must I do something else to pass the visibility change to the contained widgets? Must I directly request the widget from the QWidgetAction and then apply visibility to it directly (which seems like a hack)?


  • Lifetime Qt Champion

    Hi and welcome to devnet,

    Can you provide a minimal compilable code sample that shows the behaviour you describe ?



  • I've attempted to clip from a much larger codebase, so apologies if there are modification mistakes.

    class Base : public QWidgetAction
    {
        Q_OBJECT
    public:
        explicit Base(QWidget* parent, QString labelText = "", QString iconPath = "", Qt::AlignmentFlag alignment = Qt::AlignHCenter) :
        QWidgetAction(parent),
        mCustomWidget(nullptr),
        mParentWidget(nullptr),
        mTextLabel(nullptr),
        mAlignment(alignment),
        mLabelText(labelText),
        mIconPath(iconPath) {}
    
        virtual ~Base() {}
    
    protected:
        QWidget *mCustomWidget;
    
        QWidget *createTheWidgetSet(QWidget *parent)
        {
            if (mParentWidget == nullptr) {
                mParentWidget = new QWidget(parent);
                mCustomWidget = createCustomWidget(mParentWidget);
    
                if (mCustomWidget != nullptr) {
                    if (!mLabelText.isEmpty()) {
                        mCustomWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Ignored);
                    }
                }
    
                int rightMargin = QApplication::style()->pixelMetric(QStyle::PM_SmallIconSize);
    
                QBoxLayout* layout = new QBoxLayout(QBoxLayout::LeftToRight, mParentWidget);
                layout->setContentsMargins(1, 2, rightMargin, 2);
                if (!mLabelText.isEmpty()) {
                    QString some_calced_text{};
                    mTextLabel = new QLabel(some_calced_text, mParentWidget);
                    layout->addWidget(mTextLabel);
                } else {
                    if(mAlignment == Qt::AlignLeft){
                        int some_calced_val{20};
                        layout->addSpacing(some_calced_val);
                    }
                }
    
                if(mAlignment == Qt::AlignRight){
                    layout->addStretch();
                }
    
                layout->addWidget(mCustomWidget);
    
                if(mAlignment == Qt::AlignLeft){
                    layout->addStretch();
                }
            }
    
            setDefaultWidget(mParentWidget);
    
            return mCustomWidget;
        }
    
        virtual QWidget *createCustomWidget(QWidget *parent) = 0;
    
    private:
        Q_DISABLE_COPY(Base)
    
        QWidget *mParentWidget;
        QLabel  *mTextLabel;
        Qt::AlignmentFlag mAlignment;
        QString mLabelText;
        QString mIconPath;
    };
    
    class SpinBoxActionWidget : public Base
    {
        Q_OBJECT
        public:
            explicit SpinBoxActionWidget(QWidget* parent, QString labelText = "", QString iconPath = "") :
                Base(parent, labelText, iconPath),
                mSpinBox(nullptr)
            {
                    createTheWidgetSet(parent);
            }
    
            virtual ~SpinBoxActionWidget() {}
    
            QSpinBox* getSpinBox() const
            {
                return mSpinBox;
            }
    
        protected:
            QWidget *createCustomWidget(QWidget *parent) override
            {
                if (mSpinBox == nullptr) {
                    mSpinBox = new QSpinBox(parent);
                    mSpinBox->setFixedHeight(22);
                }
    
                return mSpinBox;
            }
    
        private:
            Q_DISABLE_COPY(SpinBoxActionWidget)
    
            QSpinBox *mSpinBox;
    };
    
    /* Elsewhere in code.... */
    {
        QMenu theMenu = new QMenu(parentWindow);
        SpinBoxActionWidget theAct = new SpinBoxActionWidget(theMenu);
        SpinBoxActionWidget theSecondAct = new SpinBoxActionWidget(theMenu);
    
        theMenu->addAction(theAct);
        theMenu->addAction(theSecondAct);
    
        /* I now assume that I can do this, and the entire entry in the menu
         * represented by "theAct" can be made visible and invisible.
         * This doesn't work however...
        theAct->setVisible(true);
        theAct->setVisible(false);
        */
    }
    
    

  • Lifetime Qt Champion

    The thing is, this is not enough to run your code. You really have to provide the complete example. Otherwise there's assumption and fiddling to be done that might not reproduce what you have on your side.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.