简体   繁体   English

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

[英]Why QAbstractButton emit all signals when using keyboard navigation?

I have a couple of custom buttons derived from QAbstractButton with autoExclusive and checkable property TRUE witch are applied to the same parent.(so the only one item can be checked at the same time). 我有一对夫妇的衍生自定义按钮QAbstractButtonautoExclusivecheckable财产TRUE女巫被应用到相同的父。(所以只有一个项目可以在同一时间进行检查)。

The parent is a QDialog and i want whenever the dialog is displayed for example item 1 get keyboard focus so the user can easily navigate between items from keyboard BUT trigger some function only if user choose an item with mouse release. 父级是一个QDialog ,我希望每当显示该对话框时,例如项1就会获得键盘焦点,以便用户可以轻松地在键盘上的项之间导航, 仅当用户选择释放鼠标的项时才触发某些功能。

When i catch the signals on keyboard navigation (for item 2 in this case) all QAbstractButton signals: 当我在键盘导航中捕获信号时(在本例中为项目2),所有QAbstractButton信号均:

clicked

pressed

released

toggled

will be triggered. 将被触发。

Why this happen ? 为什么会这样呢?

What can i do? 我能做什么?

Item and Dialog implementation: 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";
}

Why [does] this [sending of signals] happen ? 为什么[信号发送]会发生?

Because typically an application isn't going to care how the button was activated, only that it was activated. 因为通常一个应用程序是不会在意的按钮被激活方式 ,只知道它被激活。 If Qt did not emit those signals in response to keypress events, people would be forever complaining that their buttons weren't emitting the expected signals when someone manipulated them via the keyboard, and every developer would then have to manually add their own keyboard-support logic to every button to get the expected behavior. 如果Qt没有响应按键事件而发出这些信号,人们将永远抱怨当有人通过键盘对其进行操作时,其按钮没有发出预期的信号,然后每个开发人员都必须手动添加自己的键盘支持每个按钮的逻辑以获取预期的行为。

What can i do? 我能做什么?

The first thing to do is consider whether you really want to break keyboard support in your app. 首先要做的是考虑您是否真的想中断应用程序中的键盘支持。 Most people will expect to be able to activate buttons using the keyboard, and people who are unable to use a mouse (eg because they are blind and using screen-navigation software, or because their mouse isn't currently plugged in) will be unable to close your dialog if you disable keyboard support. 大多数人期望能够使用键盘来激活按钮,而无法使用鼠标的人(例如,因为他们是盲人并且正在使用屏幕导航软件,或者因为他们的鼠标当前未插入)将无法使用。如果禁用键盘支持,则关闭对话框。

Assuming you've considered that and want to go ahead anyway, I believe you can capture the keystrokes by overriding keyPressEvent(QKeyEvent *) in your button subclasses. 假设您已经考虑了这一点,并且无论如何都想继续前进,我相信您可以通过在按钮子类中重写keyPressEvent(QKeyEvent *)来捕获击键。 Your subclass implementation can check to see if the QKeyEvent that is passed in to it represents one of the offending keystrokes, and if it does, it can just call accept() on the QKeyEvent object (and do nothing else) rather than passing the keyPressEvent() call up to the superclass. 您的子类实现可以检查传递给它的QKeyEvent是否代表有问题的击键之一,如果是,则可以只对QKeyEvent对象调用accept()(什么也不做),而不是传递keyPressEvent ()调用超类。

Alternatively, you could just call setFocusPolicy(Qt::NoFocus) on your button widgets, which would prevent them from ever getting the focus, which would in turn prevent them from ever receiving keystrokes. 另外,您可以只在按钮小部件上调用setFocusPolicy(Qt :: NoFocus),这将阻止它们获得焦点,从而阻止其接收击键。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在启用/禁用它们时停止 QComboBox/QSpinBox 发出信号? - How to stop QComboBox/QSpinBox to emit signals when enabling/disabling them? QFileDialog不发出信号 - QFileDialog does not emit signals wxWidgets 2.9.1-使用多个wxStaticBoxes时键盘导航出现问题 - wxWidgets 2.9.1 - Problem with keyboard navigation when using multiple wxStaticBoxes 无法发出QThread的信号 - Can not emit QThread's signals 当用户在tableView中使用键盘箭头更改行时,如何发出信号? - How to emit signal, when user changes row with keyboard arrows in tableView? 为什么 QFileSystemWatcher 会发出多个信号? 和 QFileInfo 第一次写入零文件大小 - Why does QFileSystemWatcher emit multiple signals? and QFileInfo for the first time writes a zero file size lineEdit获得焦点时如何关闭QAbstractButton animateClick - How to turn off QAbstractButton animateClick when lineEdit has focus 单击可检查按钮时,如何避免 Qt 执行 QAbstractButton::nextCheckState()? - How to avoid Qt to execute QAbstractButton::nextCheckState() when checkable button is clicked? 将 QAbstractButton::clicked 连接到 map() 时,QSignalMapper 不起作用 - QSignalMapper doesn't work when connecting QAbstractButton::clicked to map() 如何在Qt中的另一个类中发出信号? - How to emit signals in another class in Qt?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM