s-6ren">
gpt4 book ai didi

c++ - QToolButton 在按下 Alt 后显示菜单

转载 作者:太空宇宙 更新时间:2023-11-04 12:45:33 25 4
gpt4 key购买 nike

我有一个带有关联菜单的工具按钮。

m_mainMenuButton = new ToolButton("menu.png", tr("Open menu"));
m_mainMenuButton->setMenu(m_mainMenu);
m_mainMenuButton->setPopupMode(QToolButton::InstantPopup);

我希望在用户按下并释放 Alt 时显示此菜单。这样正常的 QMenuBar 在 Windows 上被激活(我想要这个工具按钮而不是 QMenuBar)。我试过这个:

m_mainMenuButton->setShortcut(QKeySequence(Qt::Key_Alt));

但是当按下并释放 Alt 时它不显示菜单。或者这样:

auto shortcut = new QShortcut(QKeySequence(Qt::Key_Alt), this);
connect(shortcut, &QShortcut::activated, m_mainMenuButton, &QToolButton::showMenu);

这也没有做任何事情。我试图覆盖按键和释放事件,但后来我发现它会干扰其他使用 Alt 键作为修饰符的快捷键,例如“Alt+Left”。

有什么办法吗?

更新一个显示 Alt 不能用作快捷方式的最小示例。

#include <QAction>
#include <QApplication>
#include <QLabel>
#include <QMainWindow>
#include <QMenu>
#include <QShortcut>
#include <QToolButton>
#include <QVBoxLayout>

int main(int argc, char *argv[])
{
QApplication a(argc, argv);

QMainWindow w;

auto label = new QLabel();

auto menu = new QMenu(&w);
// intentionally added a shortcut which contains Alt as modifier to test it does not interfere with the menu
menu->addAction("Action", [label]{ label->setText("Trigered!"); }, QKeySequence("Alt+Left"));

auto btn = new QToolButton();
btn->setMenu(menu);
btn->setPopupMode(QToolButton::InstantPopup);

// the following lines do not have any effect, the menu is not shown when Alt is pressed and released
auto shortcut = new QShortcut(QKeySequence(Qt::Key_Alt), &w);
QObject::connect(shortcut, &QShortcut::activated, btn, &QToolButton::showMenu);

auto container = new QWidget();
auto layout = new QVBoxLayout(container);
layout->addWidget(btn);
layout->addWidget(label);
w.setCentralWidget(container);
w.show();

return a.exec();
}

最佳答案

这是一个受 Qt 在 QMenuBar 中的实现启发的版本:

class AltButton : public QToolButton {
public:
AltButton(QWidget *parent) : QToolButton(parent)
{
// To handle initial ALT-press in parent
parent->installEventFilter(this);
// If reparenting should be possible, override changeEvent
// You can also make an app-wide event filter if the button should catch all alt presses
}


protected:
bool altPressed = false;
bool eventFilter(QObject *watched, QEvent *event)
{
if (altPressed) {
// Alt-press registered before, check alt-Release
switch (event->type())
{
case QEvent::KeyPress:
case QEvent::KeyRelease:
{
QKeyEvent *kev = static_cast<QKeyEvent*>(event);
if (kev->key() == Qt::Key_Alt || kev->key() == Qt::Key_Meta) {
if (event->type() == QEvent::KeyPress)
break; // Alt-Press handled below by shortcut override
// Alt-Release. Toggle button
this->showMenu();
}
}
// fallthrough
case QEvent::MouseButtonPress:
case QEvent::MouseButtonRelease:
case QEvent::MouseMove:
case QEvent::FocusIn:
case QEvent::FocusOut:
case QEvent::ActivationChange:
case QEvent::Shortcut:
// These events cancel a alt-trigger
altPressed = false;
// Stop listening for global alt-releas
qApp->removeEventFilter(this);
break;
default:
break;
}
} else if (isVisible()) {
if (event->type() == QEvent::ShortcutOverride) {
QKeyEvent *kev = static_cast<QKeyEvent*>(event);
if ((kev->key() == Qt::Key_Alt || kev->key() == Qt::Key_Meta) && kev->modifiers() == Qt::AltModifier) {
// Alt-Press. Listen globally for alt-release
altPressed = true;
qApp->installEventFilter(this);
}
}
}
return false;
}
};

int main(int argc, char**argv) {
QApplication a(argc,argv);

QMainWindow w;

auto label = new QLabel();

auto menu = new QMenu(&w);
// intentionally added a shortcut which contains Alt as modifier to test it does not interfere with the menu
menu->addAction("Action", [label]{ label->setText("Trigered!"); }, QKeySequence("Alt+Left"));

auto btn = new AltButton(&w);
btn->setMenu(menu);
btn->setPopupMode(QToolButton::InstantPopup);

// the following lines do not have any effect, the menu is not shown when Alt is pressed and released
//auto shortcut = new QShortcut(QKeySequence(Qt::Key_Alt), &w);
//QObject::connect(shortcut, &QShortcut::activated, btn, &QToolButton::showMenu);

auto container = new QWidget();
auto layout = new QVBoxLayout(container);
layout->addWidget(btn);
layout->addWidget(label);
w.setCentralWidget(container);
w.show();

return a.exec();
}

Alt-Left 快捷键按预期工作,按钮菜单由 Alt-Pres-Release 切换。

关于c++ - QToolButton 在按下 Alt 后显示菜单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51816701/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com