在小部件中抓取QKeyEvents的好方法是什么?

时间:2016-11-01 01:01:23

标签: c++ qt keyboard

使用Qt-5.7.0,我希望有一个QSpinBox来设置超时值。该值可以是几秒或几分钟。我会在SpinBox之后放一个QLabel来说出它是什么。

现在,当用户操作控件时,我希望它从几秒钟改为几分钟,具体取决于是否按下了Shift键。因此,例如,当光标位于旋转框上但没有移位时,标签将显示Minutes,并且旋转框编号可以递增或递减。

但是,当光标位于旋转框上并按下shift时,标签将切换到Seconds,旋转框值将更改为previous_value * 60,并且值可以更改。

使用QtCreator,我将QSpinBox和QLabel放在QFrame中,所以所有内容都在正确的位置,但我没有看到任何可以抓住Shift状态的Slots。我可以在SpinBox shift函数中查看on_SB_valueChanged(),但我真的希望在按下shift按钮时发生更改,而不仅仅是当值为改变了(我发现按下了换档按钮)。

有没有一种标准的方式来管理这样的事情? (我想我可以创建一个自定义小部件来实现它,但也许有更简单的方法?)如何在QtCreator中放置这样的自定义小部件?

1 个答案:

答案 0 :(得分:1)

您可以use an event filter并将其附加到库存小部件以拦截事件,而不是扩展小部件。

以下是一些应该或多或少有效的代码,虽然我个人更喜欢使用一个小的切换按钮来在几分钟和几秒之间切换,这样会更直观,更不容易出错:

class Filter : public QObject {
    Q_OBJECT
    QLabel * l;
  public:
    Filter(QLabel * ll) : l(ll) {}
    bool eventFilter(QObject *, QEvent *e) {
      switch (e->type()) {
        case QEvent::Wheel:
        case QEvent::KeyPress:
        case QEvent::KeyRelease:
          if (QApplication::keyboardModifiers() & Qt::ShiftModifier) l->setText("shift");
          else l->setText("noshift");
      }
      return false;
    }
};

class Widget : public QWidget {
    Q_OBJECT
  public:
    Widget(QWidget *parent = 0) : QWidget(parent) {
      auto ll = new QVBoxLayout(this);
      setLayout(ll);
      ll->addWidget(l = new QLabel(this));
      ll->addWidget(s = new QSpinBox(this));
      s->installEventFilter(new Filter(l));
    }
  private:
  QLabel * l;
  QSpinBox * s;
};