为什么QAbstractButton在使用键盘导航时会发出所有信号?

时间:2016-10-12 04:11:52

标签: c++ qt qt5 qabstractbutton

我有几个自定义按钮派生自QAbstractButton,其中autoExclusivecheckable属性TRUE已应用于同一父级。(因此,只有一个项目可以在同一时间)。

父级是QDialog,我希望每当显示对话框时,例如项目1获得键盘焦点,这样用户就可以轻松地在键盘上的项目之间导航但是触发某些功能用户选择鼠标释放项目。

当我在键盘导航上捕获信号时(在这种情况下为第2项)所有QAbstractButton信号:

clicked

pressed

released

toggled

将被触发。

为什么会这样?

我该怎么办?

ItemDialog实施:

Item::Item(QWidget *parent) : QAbstractButton(parent) {
    setAutoExclusive(true);
    setCheckable(true);
}

void Item::paintEvent(QPaintEvent *) {
    QPainter p(this);
    p.setPen(Qt::NoPen);
    p.setRenderHint(QPainter::Antialiasing);
    p.setBrush(/*brush*/);
    p.drawRoundedRect(rect(), /* raduis*/, /* radius */);
    p.setRenderHint(QPainter::Antialiasing, false);

    if (isChecked()) p.drawPixmap(rect(), /*pixmap*/);
}

QSize Item::sizeHint() const {
    return QSize(/*size*/, /*size*/);
}

Dialog::Dialog(QWidget *parent) : QDialog(parent) {
    _mainLayout.setContentsMargins(24, 24, 24, 24);
    _mainLayout.setSpacing(12);

    _mainLayout.addWidget(&_item1, 0, 0);
    _mainLayout.addWidget(&_item2, 0, 1);
    _mainLayout.addWidget(&_item3, 0, 2);

    QObject::connect(&_item2, SIGNAL(clicked()), this, SLOT(onItemClicked()));
    QObject::connect(&_item2, SIGNAL(released()), this, SLOT(onItemReleased()));
    QObject::connect(&_item2, SIGNAL(pressed()), this, SLOT(onItemPPress()));
    QObject::connect(&_item2, SIGNAL(toggled(bool)), this, SLOT(onToggle(bool)));
}

void Dialog::showEvent(QShowEvent *e) {
    _item1.setFocus(Qt::TabFocusReason);
    QDialog::showEvent(e);
}

void Dialog::onItemClicked() {
        qDebug() << "CLICKED";
}
void Dialog::onItemReleased() {
        qDebug() << "RELEASED";
}
void Dialog::onItemPPress() {
        qDebug() << "PRESS";
}
void Dialog::onToggle(bool f) {
        qDebug() << "Toggle";
}

1 个答案:

答案 0 :(得分:2)

  

为什么[发送信号]会发生?

因为通常应用程序不会关心如何按钮被激活,只是它被激活了。如果Qt没有响应按键事件发出这些信号,那么当有人通过键盘操作时,人们会永远抱怨他们的按钮没有发出预期信号,然后每个开发人员都必须手动添加他们自己的键盘支持每个按钮的逻辑,以获得预期的行为。

  

我该怎么办?

要做的第一件事是考虑您是否真的想在您的应用中打破键盘支持。大多数人都希望能够使用键盘激活按钮,并且无法使用鼠标的人(例如,因为他们是盲人并使用屏幕导航软件,或者因为他们的鼠标当前未插入)将无法使用如果禁用键盘支持,请关闭对话框。

假设您已经考虑过并且想要继续进行,我相信您可以通过覆盖按钮子类中的keyPressEvent(QKeyEvent *)来捕获击键。你的子类实现可以检查传入它的QKeyEvent是否代表了一个有问题的击键,如果是,它只能在QKeyEvent对象上调用accept()(而不做其他任何事情)而不是传递keyPressEvent ()调用超类。

或者,您可以在按钮小部件上调用setFocusPolicy(Qt :: NoFocus),这样可以防止它们获得焦点,从而阻止它们接收击键。