10

3 つの QSpinBoxes (座標など) を保持する QWidget 派生クラスを取得しました。valueChanged()信号は接続され、少なくとも次の 3 つのケースで発信されます。

  1. 上下ボタン
  2. 手入力番号
  3. setValue()

ただし、を使用する場合setValue()、(3 つの) シグナルを使用したくないため、シグナルを抑制します。私の理解では、これを処理するには2つの方法があります。

  1. QObject::blockSignals()
  2. 値が明示的に設定されたかどうかを示すフラグを使用する

どちらのバリアントも機能しますが、まったく簡単ではないと思います。最初のバリアントでは、通常、すべてのシグナルをブロックしblockSignals(true)、すべての基になるウィジェットを設定する必要があります (blockSignals はアプリケーションの子 QObject をブロックしません)。2 つ目については、すべての更新メソッドでフラグを照会する必要があり、シグナルは必要ありませんが発生します。

そのような動作を防ぐ一般的な設計パターンはありますか? そうでない場合、どのバリアントが好みですか?

4

1 に答える 1

8

3 番目のオプションは、QSpinBox をサブクラス化し、そこに必要な機能を実装し、QSpinBox の代わりに派生クラスを使用することです。これにより、派生クラスに関連するすべての複雑さが隠され、QSpinBox と同じように使用できるようになります。

たとえば、次のクラス

myQSpinBox.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

myQSpinBox.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);
}

ケース 1. と 2. では発行されますが、ケース 3. では発行されず、 QSpinBoxvalueChangedNotBySet(int);のすべての機能がそのまま維持されます。

于 2013-04-02T20:49:39.627 に答える