Qt - 解决插槽上的两个连续调用,并仅执行一次操作

时间:2015-03-15 11:41:03

标签: c++ qt lambda signals-slots qt-signals

我有一个继承自CodeEditor的{​​{1}}类。当QPlainTextEdit的位置或选择发生变化时,此类必须发出请求。问题是,当发出textCursor()assembleIntellisenseRequest时,我不希望2次调用pickListSortRequestcursorPositionChanged信号。我通过将selectionChanged成员添加到bool update_来解决此问题,该成员在构造函数中设置为CodeEditor。延迟500ms只是为了清晰起见。

true

有没有更好的方法来实现这一目标?另外,在这种情况下,为什么lambda通过引用void CodeEditor::makeConnections() { auto updateRequest = [this]() { if(update_ && !textCursor().hasSelection()) { update_ = false; QTimer::singleShot(500, [this]() { update_ = true; }); emit assembleIntellisenseRequest(textCursor().blockNumber()); emit pickListSortRequest(textCursor().positionInBlock()); } }; connect(this, &CodeEditor::cursorPositionChanged, updateRequest); connect(this, &CodeEditor::selectionChanged, updateRequest); } 打印输出不等于this1:?我只是知道,this:仍然是update_

false

提前谢谢。

1 个答案:

答案 0 :(得分:2)

您可以将下一个模式应用于您的代码:

class MyClass : public QObject
{
private slots:
  void updateRequest();  

private:
  QTimer *_timer;
  CodeEditor *_editor;
};


MyClass::MyClass()
{
  // Init members
  // ...
  _timer->setSingleShot( true );
  _timer->setInterval( 0 );

  connect( _editor, &CodeEditor:: cursorPositionChanged, _timer, &QTimer::start);
  connect( _editor, &CodeEditor:: selectionChanged, _timer, &QTimer::start);
  connect( _timer, &QTimer::timeout, this, &MyClass::updateRequest );
}

在此解决方案中,计时器是“信号代理”。每次发出信号时,定时器将立即启动(当流程返回事件循环时)。每次发出的信号都会调用QTimer::start个插槽。但是start的所有调用只会向事件队列发出一次timeout信号调用。因此,当控制流将返回到事件循环时,即使发出大量信号,您的updateRequest插槽也只会被调用一次。

QTimer是替换update_变量的“Qt方式”,没有任何超时。