【问题标题】:Qt force QCheckBox to emit signal on setCheckedQt 强制 QCheckBox 在 setChecked 上发出信号
【发布时间】:2011-11-07 15:29:19
【问题描述】:

如果我调用了QCheckBox::setChecked( x ),则只有在x 与当前复选框状态不同时才会发出toggled 信号。我理解这背后的逻辑,以避免在没有任何改变的情况下发出信号。但是,在某些情况下,我有一个更复杂的小部件设置,我需要始终发出信号。这可以确保任何连接到复选框的人都将收到第一个状态。

有没有办法让QCheckBox::setChecked(bool) 无论状态是否改变都发出信号?


我现在的简单解决方法是通过执行setChecked(!x)setChecked(x) 来强制复选框进入多个状态。我希望有一种更正确的方法来做到这一点。

【问题讨论】:

    标签: qt qt4


    【解决方案1】:

    查看QAbstractButton 实现,我发现以下代码行:

    if (!d->checkable || d->checked == checked) {
        if (!d->blockRefresh)
            checkStateSet();
        return;
    }
    

    其中checkStateSet 是一个虚函数。 QCheckBox 覆盖它并仅在状态更改时发出stateChanged() 信号。 我没有对此进行测试,但我认为如果你直接调用QCheckBox::setChecked( ... )d->blockRefresh 将设置为false

    如果是这种情况,则意味着您可以将QCheckBox 子类化并将checkStateSet() 方法重写为如下所示:

    void MyCheckBox::checkStateSet()
    {
        QCheckBox::checkStateSet();
        if( m_oldState == checkState() )
        {
            // emit the signal here, as QCheckBox::checkStateSet() didn't do it.
            emit stateChanged( m_oldState );
        }
        else
        {
            // don't emit the signal as it has been emitted already,
            // but save the old state
            m_oldState = checkState();
        }
    }
    

    头文件所在的位置

    private:
        Qt::CheckState m_oldState;
    

    必须在构造函数中初始化为Qt::Unchecked

    【讨论】:

    • 这可能行得通,但由于这个原因必须子类化有点问题:你必须记住在设计器中推广,所有程序员都必须记住使用这个类。
    【解决方案2】:

    这是另一种解决方案,可能适用于您的情况,也可能不适用:

    如果您可以 100% 确定您的信号和插槽在复选框有机会更改其状态之前已连接,则假设未选中该复选框,每个已连接的类都可以安全地初始化自身。这是因为复选框在构造时始终未选中。 这样您就不必在连接信号后调用setChecked()

    但是,如果在复选框已更改后有可能连接信号,则此方法不起作用。我自己并不是 100% 喜欢这种方法,但它可能是你的一个选择。

    【讨论】:

      【解决方案3】:

      一种方法是继承 QCheckBox 并在您需要的地方实现信号的发射,例如:

      class MyCheckBox : public QCheckBox
      {
         Q_OBJECT
      public:
         MyCheckBox(QWidget *parent = 0) : QCheckBox(parent) {};
      
         virtual void setChecked(bool checked) {
                  QCheckBox::setChecked(checked); emit checkWasSet(checked);
                  };
      signals:
         void checkWasSet(bool value);
      
      };
      

      现在使用这个类而不是常规的 QCheckBox 类,您可以在设置检查状态时连接到 checkWasSet() 信号。

      【讨论】:

      • setCheckedQAbstractButton 中不是虚拟的(根据文档)。另外,对于设置状态的任何方式,我希望该机制是通用的。我还必须为其他几个类重复该模式(QCheckBox 只是我的示例)。
      【解决方案4】:

      您可以自己发出当前状态的信号:

      checkbox.stateChanged.emit(checkbox.checkState())
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-02-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多