- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
如果用户按住特定键,我想修改 QAction。您可以在 Mac 上看到类似的行为,例如,如果您拉下 Apple 菜单并按下/释放选项键 - “关于 native ”更改为“系统信息...”等。这是我想在我的应用程序中模拟的行为。
为此,我尝试覆盖 QMenuBar 和包含 QAction 的 QMenu 上的 keyPressEvent。但是,我的调试表明在显示相关 QMenu 的情况下按下任何键时,这些 keyPressEvent 函数都没有被调用。
我有点想知道这是否可能是由于在较低级别处理事件以在菜单中提供“提前输入”类型功能?我确实注意到在键入各种键时选择了不同的菜单条目,我认为这是正常行为。
如何响应 QMenuBar 或 QMenu 中的 keyPress 类型事件?
编辑:这是我试过的:
class MainMenu: public QMenuBar
{
Q_OBJECT
protected:
void keyPressEvent(QKeyEvent *event) override
{qDebug("Got Key Press Event in Menu Bar: %i",event->key());}
}
class FileMenu: public QMenu
{
Q_OBJECT
protected:
void keyPressEvent(QKeyEvent *event) override
{qDebug("Got Key Press Event in Menu: %i",event->key());}
}
It is also possible to filter all events for the entire application, by installing an event filter on the QApplication or QCoreApplication object.
"QMenu objects used in the native menu bar are not able to handle Qt events via the normal event handlers. Install a delegate on the menu itself to be notified of these changes
最佳答案
我做了一个 MCVE对于 OP 的问题。
我相信我无法重现 OP 的问题。可能是,OP 对我有其他期望。当然,菜单栏只要没有激活就不会接收按键事件。 (我暂时忽略了捷径的主题。)
在我的测试中,我总是先点击菜单栏激活菜单,然后接收按键事件。我用菜单栏和子菜单对此进行了测试。
我观察到,一旦打开子菜单,甚至两个(菜单栏和菜单)都会收到(相同的)键事件。 (考虑到 ← 和 → 作用于菜单栏,而 ↑ 和 ↓ 作用于事件菜单,这似乎是合理的。)
这是我的示例代码 testQMenuKeyEvent.cc
:
#include <QtWidgets>
class FileMenu: public QMenu {
private:
QAction qCmdNew, qCmdOpen, qCmdQuit;
bool alt;
public:
FileMenu(): QMenu(),
qCmdNew(QString::fromUtf8("New")),
qCmdOpen(QString::fromUtf8("Open")),
qCmdQuit(QString::fromUtf8("Quit")),
alt(false)
{
addAction(&qCmdNew);
addAction(&qCmdOpen);
addAction(&qCmdQuit);
// install signal handlers
connect(&qCmdNew, &QAction::triggered,
[&]() {
qDebug() << (alt ? "Reset" : "New") << "triggered";
});
connect(&qCmdOpen, &QAction::triggered,
[&]() {
qDebug() << (alt ? "Save" : "Open") << "triggered";
});
}
protected:
virtual void showEvent(QShowEvent *pQEvent) override
{
qDebug() << "FileMenu::showEvent";
update();
QMenu::showEvent(pQEvent);
}
virtual void keyPressEvent(QKeyEvent *pQEvent) override
{
qDebug() << "FileMenu::keyPressEvent";
update(pQEvent->modifiers());
QMenu::keyPressEvent(pQEvent);
}
virtual void keyReleaseEvent(QKeyEvent *pQEvent) override
{
qDebug() << "FileMenu::keyReleaseEvent";
update(pQEvent->modifiers());
QMenu::keyReleaseEvent(pQEvent);
}
private:
void update()
{
update(
(QApplication::keyboardModifiers()
& Qt::ControlModifier)
!= 0);
}
void update(bool alt)
{
qDebug() << "alt:" << alt;
if (!alt != !this->alt) {
qCmdNew.setText(QString::fromUtf8(alt ? "Reset" : "New"));
qCmdOpen.setText(QString::fromUtf8(alt ? "Save" : "Open"));
}
this->alt = alt;
}
};
int main(int argc, char **argv)
{
qDebug() << "Qt Version:" << QT_VERSION_STR;
QApplication app(argc, argv);
QMainWindow qWin;
QMenuBar qMenuMain;
QAction qCmdFile(QString::fromUtf8("File"));
FileMenu qMenuFile;
qCmdFile.setMenu(&qMenuFile);
qMenuMain.addAction(&qCmdFile);
QAction qCmdEdit(QString::fromUtf8("Edit"));
qMenuMain.addAction(&qCmdEdit);
QAction qCmdHelp(QString::fromUtf8("Help"));
qMenuMain.addAction(&qCmdHelp);
qWin.setMenuBar(&qMenuMain);
qWin.show();
return app.exec();
}
testQMenuKeyEvent.pro
我曾经建立:
SOURCES = testQMenuKeyEvent.cc
QT = widgets
$ qmake-qt5 testQMenuKeyEvent.pro
$ make && ./testQMenuKeyEvent
Qt Version: 5.9.4
FileMenu::showEvent
alt: false
New triggered
FileMenu::showEvent
alt: false
FileMenu::keyPressEvent
alt: true
Reset triggered
override
-ing 应该调用基类的重写方法以确保原始行为。 showEvent()
以及。 QAction
的信号处理程序完成的。 s。将它移动到处理程序函数本身将确保这对这些操作的其他发生也有效。 (我的意思是,这些操作可以在工具栏中“重用”。)QApplication::keyboardModifiers()
内部调用 keyPressEvent()
或 keyReleaseEvent()
它返回了错误的值,但使用了 QKeyEvent::modifiers()
相反工作正常。这让我想到,全局状态的更新是在处理这些事件之后完成的。 keyPressEvent()
没有多大帮助。 (只要菜单栏不活动(聚焦),它就不会被调用)。在这种情况下,一个 event filter可用于捕捉任何按键按下并更新菜单栏操作以防万一。 QMenu
.我发现的只是:
QMenu on macOS with Qt Build Against Cocoa
QMenu can be inserted only once in a menu/menubar. Subsequent insertions will have no effect or will result in a disabled menu item.
#include <functional>
#include <vector>
#include <QtWidgets>
class CtrlNotifier: public QObject {
private:
bool ctrl;
public:
// to be notified
std::vector<std::function<void(bool)> > sigNotify;
public:
CtrlNotifier():
ctrl(
(QApplication::keyboardModifiers() & Qt::ControlModifier)
!= 0)
{ }
bool isCtrl() const { return ctrl; }
protected:
virtual bool eventFilter(QObject *pQObj, QEvent *pQEvent) override
{
if (pQEvent->type() == QEvent::KeyPress
|| pQEvent->type() == QEvent::KeyRelease) {
const bool ctrl
= (dynamic_cast<QKeyEvent*>(pQEvent)->modifiers()
& Qt::ControlModifier)
!= 0;
if (!this->ctrl != !ctrl) {
qDebug() << "CtrlNotifier::eventFilter: Ctrl:" << ctrl;
for (std::function<void(bool)> &func : sigNotify) {
if (func) func(ctrl);
}
this->ctrl = ctrl;
}
}
// standard event processing
return QObject::eventFilter(pQObj, pQEvent);
}
};
int main(int argc, char **argv)
{
qDebug() << "Qt Version:" << QT_VERSION_STR;
QApplication app(argc, argv);
QMainWindow qWin;
QMenuBar qMenuMain;
QAction qCmdFile(QString::fromUtf8("File"));
QMenu qMenuFile;
QAction qCmdNew(QString::fromUtf8("New"));
qMenuFile.addAction(&qCmdNew);
QAction qCmdOpen(QString::fromUtf8("Open"));
qMenuFile.addAction(&qCmdOpen);
QAction qCmdQuit(QString::fromUtf8("Quit"));
qMenuFile.addAction(&qCmdQuit);
qCmdFile.setMenu(&qMenuFile);
qMenuMain.addAction(&qCmdFile);
QAction qCmdEdit(QString::fromUtf8("Edit"));
qMenuMain.addAction(&qCmdEdit);
QAction qCmdHelp(QString::fromUtf8("Help"));
qMenuMain.addAction(&qCmdHelp);
qWin.setMenuBar(&qMenuMain);
qWin.show();
// install event filter
CtrlNotifier ctrlNotifier;
app.installEventFilter(&ctrlNotifier);
// install signal handlers
ctrlNotifier.sigNotify.push_back(
[&](bool ctrl) {
qCmdNew.setText(QString::fromUtf8(ctrl ? "Reset" : "New"));
qCmdOpen.setText(QString::fromUtf8(ctrl ? "Save" : "Open"));
});
// install signal handlers
QObject::connect(&qCmdNew, &QAction::triggered,
[&]() {
qDebug() << (ctrlNotifier.isCtrl() ? "Reset" : "New") << "triggered";
});
QObject::connect(&qCmdOpen, &QAction::triggered,
[&]() {
qDebug() << (ctrlNotifier.isCtrl() ? "Save" : "Open") << "triggered";
});
// runtime-loop
return app.exec();
}
QApplication::keyboardModifiers()
内部调用 CtrlNotifier::eventFilter()
它再次返回错误的值,但使用了 QKeyEvent::modifiers()
相反工作正常。 It is also possible to filter all events for the entire application, by installing an event filter on the QApplication or QCoreApplication object. Such global event filters are called before the object-specific filters. This is very powerful, but it also slows down event delivery of every single event in the entire application; the other techniques discussed should generally be used instead.
app
上而是带来了预期的行为。 CtrlNotifier
中的非 Qt-ish 信号道歉.我正在为 VS2013 (CMake) 和 cygwin (qmake-qt5) 使用不同的构建脚本。这使得正确的 MOC 处理像往常一样有点棘手。因此,我尽量避免它的必要性。 (我并不是说在这两种情况下都不能集成 MOC。– 我曾经成功地管理过它。)关于c++ - 在 QMenuBar/QMenu 上捕获 keyPressEvent?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52747343/
大家好 我有一些代码根据一些数据生成动态填充的 QMenu(我将其称为 thisMenu)。创建 QMenu thisMenu,将一些“主”QWidget 作为父级,并添加到此 QWidget 中的
我在应用程序中的 MainWindow 之上构建了一个 QMenu MainMenu 。由于每个人都习惯了,我有以下 QMenu 主菜单: File - Edit - SuperHeavyExpert
如果没有其他原因,只是为了我自己的消遣,我想写一个全局插入运算符,这样我就可以使用花哨的代码了: aQMenu addAction(action); return menu; } 编译
Reading the Qt5 source code ,我注意到 QLabel::contextMenuEvent() 使用这种(非阻塞)样式: QMenu *menu = ... menu->se
Reading the Qt5 source code ,我注意到 QLabel::contextMenuEvent() 使用这种(非阻塞)样式: QMenu *menu = ... menu->se
使用 Qt5,假设我有一个实现其自己的上下文菜单的控件。并假设在某些情况下我想将一些项目添加到标准上下文菜单。因此,为此,我创建了一个临时 QMenu,向其中添加一些内容并附加标准菜单。像这样的东西:
代码示例: auto fileMenu = std::make_unique(this->menuBar()->addMenu("First")); fileMenu->addAction("AFir
我正在使用 QT4 并动态地向 QMenu 添加条目。是否可以对 QMenu 中的条目进行排序而不删除它并创建一个新条目? 我原本以为有一个函数可以在特定位置插入,因此我可以在插入时进行排序,但我一直
我使用 Windows,我想将样式表设置为 QMenu 以赋予其半透明背景。为了让它起作用,我首先设置 FramelessWindowHint,然后设置 WA_TranslucentBackgroun
我的情况非常具体。我想将 QAction 放入 QToolbar 并达到以下行为: 可检查带有图标的QAction。 右侧的经典箭头,用于显示菜单 通过按此箭头,我的 QDialog 应该出现在屏幕上
我有一个带有半透明背景和圆角边缘(边框半径)的 QMenu。不幸的是,Windows 7 为该菜单绘制了阴影,该阴影不适合圆角边缘。它是为普通矩形菜单绘制的阴影。 有没有 - 一种完全禁用 QMenu
我希望主窗口中有一个菜单栏,并且能够从其他类设置菜单栏中的菜单。使用 setMenuWidget 命令将覆盖第一个菜单选项,如代码所示。在我设置菜单的类中,我想我可能需要只设置一个菜单而不是菜单栏,然
我正在使用一个执行一些方法的自定义 QMenu。该菜单具有三个选项:删除行选项、切换变量选项和调试选项(打印切换变量的值)。代码未正确执行。有时调试按钮不起作用,它会突然被执行多次。切换选项需要单击两
我正在玩弄提到的 Qt 演示浏览器示例 here并在我尝试对书签处理代码进行微小更改时注意到异常情况。 我的目的是让工具栏中的书签在新选项卡而不是现有选项卡中打开。它非常适合直接位于书签选项卡上的书签
我有几个struct,带有enum和std::string,我用来填充QComboBox使用 for() 循环与他们一起使用。像这样: struct Struct { enum Enum
QMenu 显示在 QLineEdit 右键单击上。问题:如何修改此代码以在单击鼠标左键时也显示菜单? from PyQt4.QtCore import * from PyQt4.QtGui im
是否有信号/事件可用于 QMenu 撕下? 我有一个 QMenu 子类,其中有 .setTearOffEnabled(True),但如果用户点击可撕下的“栏”。 我无法使用 QtCore.Qt.Win
我有一个弹出式 QMenu 在 QListView 中显示很 multimap 标: QMenu*menu=createMenu(); QListView*list=createList(); QWi
我正在尝试构建一个菜单,其中包含一些在 QT 中不可交互的项目。我在我的 MyCustomMenuClass 中继承了 QMenu。我正在尝试将部分标题添加到我的菜单中,以便用户更清楚。 例如,它应该
我想用 QPushButton 和 QMenu 构建一个下拉列表控件,如下所示: QPushButton* menuBt = new QPushButton("Please select"); men
我是一名优秀的程序员,十分优秀!