0

我有几个从QAbstractButtonwithautoExclusivecheckable属性 TRUE 派生的自定义按钮应用于同一个父级。(因此只能同时检查一个项目)。

父级是 aQDialog并且我希望每当显示对话框时,例如项目 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";
}
4

1 回答 1

2

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

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

我能做些什么?

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

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

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

于 2016-10-12T05:41:56.780 回答