【问题标题】:In qt, how do I implement a widget that stays consistent with variables in the code在qt中,如何实现与代码中的变量保持一致的小部件
【发布时间】:2009-05-04 06:24:06
【问题描述】:

这是一个 SpinBox 示例,它将其更改写入基础变量。我遇到的主要问题是在构造小部件时调用 valueChanged。有没有更优雅的方法来做到这一点?我认为我将一个小部件连接到自身很奇怪,但 valueChanged 不是虚拟的。

class ValueWriterInt: public QSpinBox {
    Q_OBJECT

public:
    ValueWriterInt(vector<int*> const& value): myValue(value) { 
        QObject::connect(this, SIGNAL(valueChanged(int)), this, SLOT(valueChanged(int)));
    }
    ~ValueWriterInt() {}

private slots:
    void    valueChanged(int new_value) {
        for (auto it = myValue.begin(); it != myValue.end(); ++it)
            **it = new_value;
    }

private:
    vector<int*>        myValue;
};

【问题讨论】:

    标签: c++ qt qt4


    【解决方案1】:

    我认为将小部件连接到自身并没有什么特别奇怪的地方。拥有检测和响应数据更新的单一方法实际上听起来是一件好事,因为在调试时检查的故障点更少。在您的具体情况下,它会导致一些不良行为,但总的来说这是一个很好的解决方案。

    现在,在表达了自反连接并非天生不优雅的观点之后,我将建议一种不太“优雅”的解决方案,以防止在构造后调用valueChanged。您可以有一个标志来确定对象是否刚刚构造并提前返回以防止代码在构造后立即运行。在您的示例中:

    class ValueWriterInt: public QSpinBox {
    Q_OBJECT
    
    public:
        ValueWriterInt(vector<int*> const& value): myValue(value), myAfterInit(true) { 
            QObject::connect(this, SIGNAL(valueChanged(int)), this, SLOT(valueChanged(int)));
        }
        ~ValueWriterInt() {}
    
    private slots:
        void        valueChanged(int new_value) {
            if (myAfterInit) {
                myAfterInit = false;
                return;
            }
            for (auto it = myValue.begin(); it != myValue.end(); ++it)
                    **it = new_value;
        }
    
    private:
        vector<int*>                myValue;
        boolean                     myAfterInit;
    };
    

    这是一个不错的解决方案。它至少会给你你想要的行为,直到(如果)你能找到一个更优雅的方法。

    【讨论】:

    • 谢谢。这就是我最终所做的,但获得独立确认非常令人放心。 valueChanged 比我想象的更频繁地被调用。例如,调用“setIndexWidget”会导致在小部件上调用 valueChanged。布尔也有帮助。再次感谢!
    【解决方案2】:

    那么你想在这里完成什么?是的,valueChanged 不是虚拟的——为什么它应该是,你的对象应该直接将它们自己的槽连接到它们想要响应的任何信号,不是吗?

    【讨论】:

    • 虚拟呼叫比信号/插槽更有效。不过,对于任何由 UI 驱动的东西来说,这并不重要。
    • 我正在尝试构建一个参数窗格,其中窗格上的自定义小部件位于树中。结果比我想象的要困难得多......
    【解决方案3】:

    我认为除了使用 SIGNAL-SLOT 连接之外别无选择。但是,我会更改插槽的名称,因此它与信号的名称不同。

    有趣的是,即使尚未完成连接,如何调用插槽也是如此。我怀疑更改插槽的名称会解决这个问题。

    【讨论】:

    • 两个优点。谢谢。为了确定,我最终更改了名称。而且,我发现在使用 setIndexWidget() 将小部件插入树时调用了信号。
    • 在构造时调用 valueChanged(int) 就很好了。毕竟它是一个信号,而不是一个槽。
    猜你喜欢
    • 2010-10-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-24
    • 2022-01-12
    • 2021-04-27
    • 1970-01-01
    • 2019-02-20
    • 1970-01-01
    相关资源
    最近更新 更多