0

我正在使用 QStackedWidget 项目。但是第一次需要时间,一段时间后它可以正常工作。

mymainwindow::mymainwindow() : QMainWindow()
{

    stack = new QStackedWidget();
    list = new QListWidget();
    stack->addWidget(new QLineEdit("Hello U have clicked the first menu"));
    stack->addWidget(new QLineEdit("Second ListWidget Item"));
    stack->addWidget(new QLineEdit("Last Widget Item"));

    widget = new QWidget();
    QLabel *label = new QLabel("Main Window");

    list->addItem("New Item 1");
    list->addItem("New Item 2");
    list->addItem("New Item 3");
    list->setFixedSize(200,100);

    QVBoxLayout *vertical = new QVBoxLayout();
    vertical->addWidget(label);
    vertical->addWidget(list);
    vertical->addWidget(stack);
    stack->hide();

    widget->setLayout(vertical);
    setCentralWidget(widget);
}

void mymainwindow::keyPressEvent(QKeyEvent *event)
{

    switch (event->key()) {

    case Qt::Key_Down:
        connect(list,SIGNAL(currentRowChanged(int)),stack,SLOT(setCurrentIndex(int)));
        break;
    case Qt::Key_Up:
        connect(list,SIGNAL(currentRowChanged(int)),stack,SLOT(setCurrentIndex(int)));
        break;
    case Qt::Key_Enter:
        stack->show();
        break;
    case Qt::Key_Escape:
        stack->hide();
        break;

    }
}
4

2 回答 2

4

出色地 :

  • 您正在覆盖QMainWindow::keyPressEvent(QKeyEvent *event)并完全无视默认实现。
  • 每次按键时 Qobject::connect 都是错误的。你似乎对它的作用有自己的解释。阅读文档
  • 不能听主窗口的按键来知道列表小部件的项目正在改变。
  • 快捷方式的正确做法是添加一个Qaction,然后将快捷方式关联到该操作。为什么?如果内部的小部件stack需要接收“Enter”键事件(如 a QButton),那么您的 UI 将完全是虚假的,因为您同时在操纵可见性。

基本上你想要的是将连接移动到窗口的构造函数,并确保始终处理关键事件

mymainwindow::mymainwindow() : QMainWindow()
{

    stack = new QStackedWidget();
    list = new QListWidget();
    stack->addWidget(new QLineEdit("Hello U have clicked the first menu"));
    stack->addWidget(new QLineEdit("Second ListWidget Item"));
    stack->addWidget(new QLineEdit("Last Widget Item"));

    widget = new QWidget();
    QLabel *label = new QLabel("Main Window");

    list->addItem("New Item 1");
    list->addItem("New Item 2");
    list->addItem("New Item 3");
    list->setFixedSize(200,100);

    QVBoxLayout *vertical = new QVBoxLayout();
    vertical->addWidget(label);
    vertical->addWidget(list);
    vertical->addWidget(stack);
    stack->hide();

    connect(list,SIGNAL(currentRowChanged(int)),stack,SLOT(setCurrentIndex(int)));
    list->setCurrentRow(2);//last, to test 

    widget->setLayout(vertical);
    setCentralWidget(widget);
}


void mymainwindow::keyPressEvent(QKeyEvent *event)
{

    switch (event->key()) {

    case Qt::Key_Enter:
        stack->show();
        break;
    case Qt::Key_Escape:
        stack->hide();
        break;
    }
    QMainWindow::keyPressEvent(event);
}

尽管如此,这仍然是一场噩梦。

编辑:
如果焦点在列表小部件上,使用键盘更改列表中的行将触发信号。

于 2014-01-08T11:13:20.813 回答
1

我个人建议根据我之前的评论将连接从您的事件移动到构造函数,因为这将是一个更简洁的设计,尽管我们不太了解您想要实现的目标。因此,根据您的要求,我在下面提供了一些代码,我您可以这样做:

...
case Qt::Key_Down:
    connect(list,SIGNAL(currentRowChanged(int)),stack,SLOT(setCurrentIndex(int)));
    break;
case Qt::Key_Up:
    connect(list,SIGNAL(currentRowChanged(int)),stack,SLOT(setCurrentIndex(int)));
    break;
...

至:

我的主窗口.h

mymainwindow : public QMainWindow
{
    ...
    QTimer m_timer;
    bool m_ready;
};

我的主窗口.cpp

mymainwindow::mymainwindow()
    : QMainWindow()
    , m_ready(false)
{

    stack = new QStackedWidget();
    list = new QListWidget();
    stack->addWidget(new QLineEdit("Hello U have clicked the first menu"));
    stack->addWidget(new QLineEdit("Second ListWidget Item"));
    stack->addWidget(new QLineEdit("Last Widget Item"));

    widget = new QWidget();
    QLabel *label = new QLabel("Main Window");

    list->addItem("New Item 1");
    list->addItem("New Item 2");
    list->addItem("New Item 3");
    list->setFixedSize(200,100);

    QVBoxLayout *vertical = new QVBoxLayout();
    vertical->addWidget(label);
    vertical->addWidget(list);
    vertical->addWidget(stack);
    stack->hide();

    widget->setLayout(vertical);
    setCentralWidget(widget);

    connect(&m_timer, SIGNAL(timeout()), SLOT(delayEvent()));
    m_timer.setSingleShot(true);
    m_timer.start(5000);
}

void mymainwindow::delayEvent()
{
    m_ready = true;
}


void mymainwindow::keyPressEvent(QKeyEvent *event)
{

    switch (event->key()) {

    case Qt::Key_Down:
        if (m_ready)
             connect(list,SIGNAL(currentRowChanged(int)),stack,SLOT(setCurrentIndex(int)), Qt::UniqueConnection);
        break;
    case Qt::Key_Up:
        if (m_ready)
            connect(list,SIGNAL(currentRowChanged(int)),stack,SLOT(setCurrentIndex(int)), Qt::UniqueConnection);
        break;
    case Qt::Key_Enter:
        stack->show();
        break;
    case Qt::Key_Escape:
        stack->hide();
        break;

    }
}

然后,将此变量用于事件,以查看您是否“准备好”。此外,您需要在连接时使用 Qt::UniqueConnection 作为第五个参数以避免重复连接,或者为此目的仅使用 m_ready 保护或任何其他参数。

但实际上,这听起来像是一个可疑的设计。

于 2014-01-08T11:21:36.337 回答