键盘事件QMainWindow QMainWindow

时间:2017-08-14 12:11:54

标签: qt

我正在编写一个应用程序,该应用程序将在具有一些硬件自定义按钮(映射到功能键组合)的屏幕上使用。每个按钮用于更改显示的屏幕,所以我认为堆叠的小部件似乎是合理的。

开发我已经创建了一个调试窗口,它将这些按钮作为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());
}

1 个答案:

答案 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编译和测试:

Snapshot of MCVE

注意:

我测试了点击按钮以及使用相应的功能键。因此,我将焦点设置为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再次编译和测试:

Snapshot of MCVE (V2)

注意:

QLineEdit被聚焦(默认情况下),而功能键已被用于切换QStackLayout的当前索引。