首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在QWidgetAction的子类中设置小部件的可见性

如何在QWidgetAction的子类中设置小部件的可见性
EN

Stack Overflow用户
提问于 2018-01-18 08:15:38
回答 1查看 767关注 0票数 7

Qt5.6.3,eglfs Linux平台。

我有一个从QWidgetAction派生的类的选择。QWidgetActions都是从菜单中获得的,它们包含的小部件来自同一个菜单。包含的小部件都被设置为QWidgetAction的默认小部件。没有什么是从QWidgetAction中重新实现的。

我认为设置QWidgetAction的可见性将自动设置包含在其中的自定义小部件集的可见性。这不是真的吗,因为这样做肯定没有按要求显示和隐藏小部件!?为了将可见性更改传递给包含的小部件,我必须做其他事情吗?我必须直接从QWidgetAction请求小部件,然后直接对其应用可见性(这似乎是一个黑客)?

我对QWidgetActions应该如何实现感兴趣。文档几乎不存在,所以我所追求的是人们对它们的体验。我有间歇性的问题,看上去像是一个定制小部件的双重删除和可见性,而不是它应该做的事情。

代码语言:javascript
复制
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, either the widget remains visible,
     * or is partially hidden.
    theAct->setVisible(true);
    theAct->setVisible(false);
    */
}
EN

回答 1

Stack Overflow用户

发布于 2018-02-08 17:06:17

您没有重新实现接口,这就是它不能工作的原因。

首先,请注意,QWidgetAction来自QAction,而不是QWidget;然而,它确实有一个setVisible()函数,它实际上只是将调用转发到该操作创建的所有小部件。

您必须重新实现QWidgetAction::createWidget(parent)以添加新的小部件;您的createCustomWidget没有做任何有用的事情。下面是一个非常简单的例子:

代码语言:javascript
复制
class SpinAction : public QWidgetAction
{
    Q_OBJECT
public:
    SpinAction(QObject* parent) : QWidgetAction(parent) {}
    virtual ~SpinAction() {}
    QWidget* createWidget(QWidget* parent) { return new QSpinBox(parent); }
 // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 // reimplement this function
};

您可以将您的操作添加到任何您想要的容器,菜单,工具栏等.这个例子将为每个容器创建一个新的小部件,和这些创建的小部件不会是同步的(例如,在spinbox值上)。

我只是在一个主窗口中测试了它,在菜单和工具栏中添加了一个小部件操作,并且调用setVisible()是完美的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48316599

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档