明确设置值时抑制Qt信号的正确方法是啥
Posted
技术标签:
【中文标题】明确设置值时抑制Qt信号的正确方法是啥【英文标题】:What is the right way to suppress Qt signals when values are explicitely set明确设置值时抑制Qt信号的正确方法是什么 【发布时间】:2013-04-02 11:00:03 【问题描述】:我从 QWidget 派生类中获得了一个包含三个 QSpinBox(例如坐标)的派生类。 valueChanged()
信号至少在以下三种情况下被连接并发出:
-
上/下按钮
手动输入号码
setValue()
但是,当使用setValue()
时,我想抑制信号,因为我不想拥有(三个)信号。据我了解,有两种方法可以处理:
QObject::blockSignals()
使用一个标志来指示值是否被明确设置
两种变体都有效,但我认为它们根本不是直截了当的:对于第一个,我通常会阻止所有信号并且我需要为所有底层小部件设置 blockSignals(true)
(blockSignals 不会阻止子 QObjects我的应用程序)。对于第二个,我需要在每个更新方法中查询标志,并且虽然我不需要它们,但会引发信号。
是否有任何通用设计模式可以防止此类行为?如果不是,您更喜欢哪种变体?
【问题讨论】:
【参考方案1】:第三个选项是继承 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. 中发出 valueChangedNotBySet(int);
,但在情况 3. 中不会发出,保持所有 QSpinBox 功能完整
【讨论】:
嗨,伊利亚,谢谢。你是绝对正确的——这是第三个(也是迄今为止最干净的)变体。但是,我需要重新实现(一次)各种小部件(QSpinBox 只是一个示例) - QLineEdit、QComboBox、QDoubleSpinBox、...。 我不确定是否需要重新实现 QLineEdit - 因为 QLineEdit 有信号 textChanged(const QString & text) 和 textEdited(const QString & text) 允许区分编辑类型。同样可能适用于 QComboBox... 只有当一切都发生在 UI 线程中时才会起作用。当跨多个线程有信号/槽连接链时,valueBeingSet
将在再次(无限)发出valueChnaged
信号之前设置为false
,因为事件处理程序将被异步调用。
@mescalinum 是的,此示例假设单个 ui 线程。但是,我认为它可以通过添加 QWaitCondition 成员变量并在 QSpinBox::setValue(val); 之后等待它来轻松适应您描述的场景。在设置 valueBeingSet = false 之前; (从 On_valueChanged 唤醒等待条件)。以上是关于明确设置值时抑制Qt信号的正确方法是啥的主要内容,如果未能解决你的问题,请参考以下文章