10

我从 QWidget 派生类中得到了一个包含三个 QSpinBoxes(例如坐标)的类。valueChanged()至少在以下三种情况下,信号被连接并发出:

  1. 上/下按钮
  2. 手动输入的号码
  3. setValue()

但是,在使用时setValue(),我想抑制信号,因为我不想拥有(三个)信号。据我了解,有两种方法可以解决这个问题:

  1. QObject::blockSignals()
  2. 使用指示值是否被明确设置的标志

两种变体都有效,但我认为它们根本不是直截了当的:对于第一个,我通常会阻止所有信号并且我需要blockSignals(true)为所有底层小部件设置(blockSignals 不会阻止我的应用程序中的子 QObjects)。对于第二个,我需要在每个更新方法中查询标志,并且尽管我不需要它们,但会引发信号。

是否有任何通用的设计模式可以防止这种行为?如果不是,您更喜欢哪种变体?

4

1 回答 1

8

第三个选项是继承 QSpinBox,在那里实现所需的功能,并使用派生类而不是 QSpinBox - 这隐藏了派生类中所有相关的复杂性,并允许您像使用 QSpinBox 一样使用它。

例如,下面的类

我的QSpinBox.h

#ifndef MYQSPINBOX_H
#define MYQSPINBOX_H

#include <QSpinBox>

class myQSpinBox : public QSpinBox
{
    Q_OBJECT
public:
    myQSpinBox(QWidget * parent = 0 );
protected:
    bool valueBeingSet;
public slots:
    void setValue (int val);
private slots:
    void On_valueChanged(int val);
signals:
    void valueChangedNotBySet(int val);
};

#endif // MYQSPINBOX_H

我的QSpinBox.cpp

#include "myQSpinBox.h"

myQSpinBox::myQSpinBox(QWidget * parent)
        : QSpinBox(parent)
        , valueBeingSet(false)
{
    connect(this,SIGNAL(valueChanged(int)),this,SLOT(On_valueChanged(int)));
}

void    myQSpinBox::setValue ( int val )
{
    valueBeingSet = true;
    QSpinBox::setValue(val);
    valueBeingSet = false;
}

void myQSpinBox::On_valueChanged(int val)
{
    if(!valueBeingSet)
        emit valueChangedNotBySet(val);
}

valueChangedNotBySet(int);在情况 1. 和 2. 中发出,但不会在情况 3. 中发出,保持所有 QSpinBox 功能不变

于 2013-04-02T20:49:39.627 回答