我正在编写一个应用程序,该应用程序将在具有一些硬件自定义按钮(映射到功能键组合)的屏幕上使用。每个按钮用于更改显示的屏幕,所以我认为堆叠的小部件似乎是合理的。
开发我已经创建了一个调试窗口,它将这些按钮作为QPushButtons,使用" normal" Mainwindow嵌入式。在发布版本中运行时,我打算将其作为主窗口运行
这一切都很好,但关键的新闻事件并没有像我预期的那样传播。阅读Qt文档,它表明具有焦点的窗口小部件将接收事件,因此我假设堆叠窗口小部件中显示的窗口小部件将接收按键,但调试窗口始终接收关键事件,无论我设置的任何焦点策略< / p>
调试窗口:
DebugWindow::DebugWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::GVADemo)
{
ui->setupUi(this);
MainWindow* main = new MainWindow(this);
QLayout* layout = new QHBoxLayout;
layout->addWidget(main);
layout->setContentsMargins(0,0,0,0);
ui->frame->setLayout(layout);
}
void GVADemo::keyPressEvent(QKeyEvent *event)
{
qDebug("GVADemo keyPressEvent %d", event->key());
}
主窗口:
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
{
ui->setupUi(this);
Screen* screen1 = new Screen();
QStackedWidget* stackedWidget = new QStackedWidget(this);
stackedWidget->addWidget(screen1);
stackedWidget->setCurrentWidget(screen1);
setCentralWidget(stackedWidget);
}
void MainWindow::keyPressEvent(QKeyEvent *event)
{
qDebug("MainWindow keyPressEvent %d", event->key());
}
堆叠小部件中的屏幕示例:
Screen::Screen(QWidget *parent) : QWidget(parent), ui(new Ui::Screen)
{
ui->setupUi(this);
}
void SAScreen::keyPressEvent(QKeyEvent *event)
{
qDebug("Screen keyPressEvent %d", event->key());
}
答案 0 :(得分:1)
使用快捷键可以实现预期效果(实际上非常简单)。
我准备了MCVE类似于问题中描述的内容:
// Qt header:
#include <QtWidgets>
int main(int argc, char **argv)
{
qDebug() << "Qt Version: " << QT_VERSION_STR;
// main application
#undef qApp // undef macro qApp out of the way
QApplication qApp(argc, argv);
// setup GUI
QWidget qWin;
QGridLayout qGrid;
enum { N = 5 };
QStackedLayout qStack;
struct Pane {
QWidget qWidget;
QVBoxLayout qVBox;
QLabel qLbl;
QLineEdit qTxt;
} panes[N];
for (int i = 0; i < N; ++i) {
Pane &pane = panes[i];
pane.qLbl.setText(QString::fromUtf8("<b>Pane %0</b>").arg(i + 1));
pane.qLbl.setTextFormat(Qt::RichText);
pane.qVBox.addWidget(&pane.qLbl, 1, Qt::AlignCenter);
pane.qVBox.addWidget(&pane.qTxt);
pane.qWidget.setLayout(&pane.qVBox);
qStack.addWidget(&pane.qWidget);
}
qGrid.addLayout(&qStack, 0, 0, 1, N);
qGrid.setRowStretch(0, 1);
QPushButton qBtns[N];
for (int i = 0; i < N; ++i) {
QPushButton &qBtn = qBtns[i];
qBtn.setText(QString::fromUtf8("F%0").arg(i + 1));
qBtn.setShortcut(Qt::Key_F1 + i);
qGrid.addWidget(&qBtn, 1, i);
}
qWin.setLayout(&qGrid);
qWin.show();
// install signal handlers
for (int i = 0; i < N; ++i) {
QPushButton &qBtn = qBtns[i];
QObject::connect(&qBtn, &QPushButton::clicked,
[&qStack, i](bool) { qStack.setCurrentIndex(i); });
}
// run application
return qApp.exec();
}
我在Windows 10(64位)中使用VS2013和Qt5.6编译和测试:
注意:
我测试了点击按钮以及使用相应的功能键。因此,我将焦点设置为QLineEdit
,以确保它独立于当前关注的小部件。
<强>更新强>
在OP中,按钮是硬件按钮。因此,我修改了样本的第一个版本,使其无需QPushButton
。使用QAction
直接添加到主窗口(使用QWidget::addAction()
)可以实现相同的效果:
// Qt header:
#include <QtWidgets>
int main(int argc, char **argv)
{
qDebug() << "Qt Version: " << QT_VERSION_STR;
// main application
#undef qApp // undef macro qApp out of the way
QApplication qApp(argc, argv);
// setup GUI
QWidget qWin;
QGridLayout qGrid;
enum { N = 5 };
QStackedLayout qStack;
struct Pane {
QWidget qWidget;
QVBoxLayout qVBox;
QLabel qLbl;
QLineEdit qTxt;
} panes[N];
for (int i = 0; i < N; ++i) {
Pane &pane = panes[i];
pane.qLbl.setText(QString::fromUtf8("<b>Pane %0</b>").arg(i + 1));
pane.qLbl.setTextFormat(Qt::RichText);
pane.qVBox.addWidget(&pane.qLbl, 1, Qt::AlignCenter);
pane.qVBox.addWidget(&pane.qTxt);
pane.qWidget.setLayout(&pane.qVBox);
qStack.addWidget(&pane.qWidget);
}
qGrid.addLayout(&qStack, 0, 0, 1, N);
qGrid.setRowStretch(0, 1);
QLabel qLbls[N];
for (int i = 0; i < N; ++i) {
QLabel &qLbl = qLbls[i];
qLbl.setText(QString::fromUtf8("F%0").arg(i + 1));
qGrid.addWidget(&qLbl, 1, i);
}
qWin.setLayout(&qGrid);
QAction *pQCmds[N];
for (int i = 0; i < N; ++i) {
QAction *pQCmd = pQCmds[i] = new QAction(&qWin);
pQCmd->setShortcut(Qt::Key_F1 + i);
qWin.addAction(pQCmd);
}
qWin.show();
// install signal handlers
for (int i = 0; i < N; ++i) {
QObject::connect(pQCmds[i], &QAction::triggered,
[&qStack, i](bool) { qStack.setCurrentIndex(i); });
}
// run application
return qApp.exec();
}
我在Windows 10(64位)中使用VS2013和Qt5.6再次编译和测试:
注意:
QLineEdit
被聚焦(默认情况下),而功能键已被用于切换QStackLayout
的当前索引。