Qt 在修改更改相关项目信息的文本框(QLineEdit)时,如何避免无限循环?
我在一个小部件中有几个字段,每个字段都会影响一个项目的行为,更改其中一些字段会更改其他字段 我在某处读到,行编辑的Qt 在修改更改相关项目信息的文本框(QLineEdit)时,如何避免无限循环?,qt,textbox,infinite-loop,Qt,Textbox,Infinite Loop,我在一个小部件中有几个字段,每个字段都会影响一个项目的行为,更改其中一些字段会更改其他字段 我在某处读到,行编辑的editingFinished()信号仅由用户操作触发,而不是由代码更改触发。。。这是真的吗 connect(m_lineEdit1, SIGNAL(editingFinished()), this, SLOT(m_lineEdit1Changed())); connect(m_lineEdit2, SIGNAL(editingFinished()), this, SLOT(m_li
editingFinished()
信号仅由用户操作触发,而不是由代码更改触发。。。这是真的吗
connect(m_lineEdit1, SIGNAL(editingFinished()), this, SLOT(m_lineEdit1Changed()));
connect(m_lineEdit2, SIGNAL(editingFinished()), this, SLOT(m_lineEdit2Changed()));
connect(this, SIGNAL(someSignal()), this, SLOT(updateData()));
void m_lineEdit1Changed()
{
changedata1();
emit someSignal();
}
void m_lineEdit2Changed()
{
changedata2();
emit someSignal();
}
void updateData()
{
m_lineEdit1.setText(fromdata);
m_lineEdit2.setText(fromdata);
}
如果我更改m_lineEdit1
,并更新整个小部件(通过代码m_lineEdit2
),我会在m_lineEdit2Changed()
这将导致无限的更新循环
我能做些什么来避免这个问题?避免这个问题的一种方法是使用这个函数 在您的示例中,您将执行以下操作:
void updateData()
{
m_lineEdit1.blockSignals(true);
m_lineEdit1.setText(fromdata);
m_lineEdit1.setText(fromdata);
m_lineEdit1.blockSignals(false);
}
blockSignals()调用阻止对象在您更改行编辑中的数据时发送任何信号。阻塞信号有点像是一种方法的重锤。您可以使用sentinel类显式防止递归:
#define SENTINEL_STRINGIFY(x) #x
#define SENTINEL_TOSTRING(x) SENTINEL_STRINGIFY(x)
#define SENTINEL_AT __FILE__ ":" SENTINEL_TOSTRING(__LINE__)
class Sentinel {
Q_DISABLE_COPY(Sentinel);
static QMutex m_mutex;
static QSet<QString> m_sentinels;
QString const m_sentinel;
bool const m_ok;
static bool checkAndSet(const QString & sentinel) {
QMutexLocker lock(&m_mutex);
if (m_sentinels.contains(sentinel)) return false;
m_sentinels.insert(sentinel);
return true;
}
public:
explicit Sentinel(const char * sentinel) :
m_sentinel(sentinel), m_ok(checkAndSet(m_sentinel)) {}
~Sentinel() {
if (!m_ok) return;
QMutexLocker lock(&m_mutex);
m_sentinels.remove(m_sentinel);
}
bool operator()() const { return m_ok; }
};
QMutex Sentinel::m_mutex;
QSet<QString> Sentinel::m_sentinels;
...
void Foo::m_lineEdit1Changed()
{
Sentinel s(SENTINEL_AT);
if (!s) return; // exit if this method is on the call stack
...
changedata1();
emit someSignal();
}
#定义SENTINEL_STRINGIFY(x)#x
#定义SENTINEL_-TOSTRING(x)SENTINEL_-STRINGIFY(x)
#在文件中定义哨兵“:“哨兵”到字符串(uuu行)
班哨{
Q_禁用_复制(Sentinel);
静态qmutexm_互斥体;
静态QSet m_哨兵;
QString const m_sentinel;
布尔常数m_ok;
静态布尔校验集(常量QString和sentinel){
QMutexLocker锁(&m_互斥锁);
如果(m_sentinels.contains(sentinel))返回false;
m_sentinel.插入(sentinel);
返回true;
}
公众:
显式Sentinel(常量字符*Sentinel):
m_sentinel(sentinel),m_ok(checkAndSet(m_sentinel)){}
~Sentinel(){
如果(!m_ok)返回;
QMutexLocker锁(&m_互斥锁);
m_sentinel.移除(m_sentinel);
}
布尔运算符()()常量{return m_ok;}
};
QMutex Sentinel::m_互斥体;
QSet哨兵:m_哨兵;
...
void Foo::m_lineEdit1Changed()
{
哨兵s(哨兵AT);
if(!s)return;//如果此方法位于调用堆栈上,则退出
...
changedata1();
发出某种信号();
}
这是线程安全的,可以从任何线程使用。这是Qt在5.3中引入的
QSignalBlocker
类的一种非常常见的技术,它克服了上述手动方式的一些缺陷。