gpt4 book ai didi

c++ - QT - QAction::eventFilter:不明确的快捷方式重载

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:28:36 24 4
gpt4 key购买 nike

在这里和其他类似 qtcentre 的地方搜索我看到这个问题已经出现但似乎无法让它工作。我有一个带有 QSplitterMainWindow 小部件,它包含两个 Pane 小部件(从 QFrame 子类化)。每个 Pane 都有一个菜单栏,其中包含相同的相关QActions/Shortcuts

我已经尝试了 ShortcutContextssetShortcutContext() 的所有组合。

WindowShortcutApplicationShortcut 上下文给出了预期的“不明确的快捷方式过载”。

虽然 WidgetShortcutWidgetWithChildrenShortcut 都什么都不做。

如果我手动激活菜单,它们当然可以正常工作。我还尝试过使用重载的 enterEvent() 强制关注父小部件。

有什么想法吗?

谢谢。

主.h

#include <QMainWindow>
#include <QFrame>

QT_BEGIN_NAMESPACE
class QAction;
class QMenu;
class QHBoxLayout;
class QSplitter;
class QWidget;
QT_END_NAMESPACE

class Pane: public QFrame
{
Q_OBJECT

public:
Pane(QWidget* parent = 0);

protected:
void enterEvent(QEvent *event);
void leaveEvent(QEvent *event);

private:
void createMenus();

QMenuBar * m_menuBar;

private Q_SLOTS:
void split();
};

class MainWindow : public QMainWindow
{
Q_OBJECT

public:
MainWindow();

private:
void createActions();
void createMenus();
void setupUi(QMainWindow *MainWindow);

QMenu *fileMenu;
QAction *exitAct;

QWidget *centralwidget;
QHBoxLayout *horizontalLayout;
QSplitter *splitter;
QFrame *frame;
QFrame *frame_2;
};

main.cpp

#include <iostream>
#include <QApplication>
#include <QMainWindow>
#include <QSplitter>
#include <QFrame>
#include <QMenuBar>
#include <QBoxLayout>
#include "main.h"

Pane::Pane(QWidget* parent) :
QFrame(parent)
{
setFrameShape(QFrame::StyledPanel);
setFrameShadow(QFrame::Raised);

QVBoxLayout *layout = new QVBoxLayout;
QFrame::setLayout(layout);

m_menuBar = new QMenuBar;
QWidget *m_widget = new QWidget;

layout->addWidget(m_menuBar);
layout->addWidget(m_widget);
layout->setContentsMargins(2, 2, 2, 2);

show();

createMenus();
}

void
Pane::enterEvent(QEvent *event)
{
std::cout << "enter" << std::endl;
setFocus();
setStyleSheet("QFrame { border: 1px solid rgb(127, 127, 0); }");
if (focusWidget())
std::cout << "focuswidget = " << focusWidget()->objectName().toUtf8().constData() << std::endl;
}

void
Pane::leaveEvent(QEvent *event)
{
std::cout << "leave" << std::endl;
clearFocus();
setStyleSheet("QFrame { border: 1px solid rgb(64, 64, 64); }");
}

void
Pane::split()
{
std::cout << "split pane" << std::endl;
}

void
Pane::createMenus()
{
QMenu *paneMenu = m_menuBar->addMenu(tr("&Pane"));

QAction *paneSplitAct = new QAction(tr("Split"), this);
paneSplitAct->setShortcut(Qt::Key_S);
paneSplitAct->setShortcutContext(Qt::WidgetWithChildrenShortcut);
paneSplitAct->setStatusTip(tr("Split Pane"));
connect(paneSplitAct, SIGNAL(triggered()), this, SLOT(split()));
paneMenu->addAction(paneSplitAct);
}

MainWindow::MainWindow()
{
setupUi(this);

createActions();
createMenus();
}

void MainWindow::createActions()
{
exitAct = new QAction(tr("E&xit"), this);
exitAct->setShortcuts(QKeySequence::Quit);
exitAct->setStatusTip(tr("Exit the application"));
connect(exitAct, SIGNAL(triggered()), this, SLOT(close()));
}

void MainWindow::createMenus()
{
fileMenu = menuBar()->addMenu(tr("&File"));
fileMenu->addAction(exitAct);
}


void MainWindow::setupUi(QMainWindow *MainWindow)
{
if (MainWindow->objectName().isEmpty())
MainWindow->setObjectName(QString::fromUtf8("MainWindow"));

MainWindow->resize(800, 600);
centralwidget = new QWidget(MainWindow);
centralwidget->setObjectName(QString::fromUtf8("centralwidget"));
horizontalLayout = new QHBoxLayout(centralwidget);
horizontalLayout->setObjectName(QString::fromUtf8("horizontalLayout"));
splitter = new QSplitter(centralwidget);
splitter->setObjectName(QString::fromUtf8("splitter"));
splitter->setOrientation(Qt::Horizontal);

frame = new Pane(splitter);
frame->setObjectName(QString::fromUtf8("frame"));
splitter->addWidget(frame);

frame_2 = new Pane(splitter);
frame_2->setObjectName(QString::fromUtf8("frame_2"));
splitter->addWidget(frame_2);

horizontalLayout->addWidget(splitter);

MainWindow->setCentralWidget(centralwidget);

QMetaObject::connectSlotsByName(MainWindow);
}

int main(int argc, char *argv[])
{
QApplication app(argc, argv);
app.setOrganizationName("Trolltech");
app.setApplicationName("Application Example");
MainWindow mainWin;
mainWin.show();
return app.exec();
}

主程序

HEADERS       = main.h
SOURCES = main.cpp
CONFIG += no_keywords

更新:Pane::createMenus() 的末尾添加一个 addAction(paneSplitAct) 调用并结合使用 Qt::WidgetShortcut 上下文似乎可以提供我想要什么。

根据我对文档的理解,这应该在小部件中创建上下文菜单。我似乎没有得到一个(我假设单击鼠标右键)但是没关系,因为我不想要一个。 eventEvent()leaveEvent() 重写仍然需要正确设置焦点。

最佳答案

我遇到过类似的问题:2 个不同的小部件具有相同的操作快捷方式(小部件之间的不同操作)。只要应用程序中只有一个小部件可见,一切正常。一旦两者都可见,我就收到了这条“模棱两可的快捷方式过载”消息。

解决方案是:两个 Action 的上下文都必须正确设置为 Qt::WidgetWithChildrenShortcut,然后它工作正常 - 只是根据当前焦点。

如果只有一个操作具有正确的上下文,则触发具有默认上下文的操作并显示消息。

如果两个操作都没有设置上下文(默认),则触发最后创建的操作并显示消息。

因此,如果您在任何地方添加带有快捷方式的操作,请记住考虑正确的上下文并进行设置,要有限制!

关于c++ - QT - QAction::eventFilter:不明确的快捷方式重载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10345565/

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