延迟在qt中显示QStackedWidget项目

时间:2014-01-08 09:29:48

标签: c++ qt qwidget qtgui qt-events

我正在使用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;

    }
}

2 个答案:

答案 0 :(得分:4)

嗯:

  • 您正在覆盖QMainWindow::keyPressEvent(QKeyEvent *event)并完全忽略默认实施。
  • Qobject ::每次按键连接都是错误的。你似乎对它的作用有自己的解释。 阅读文档
  • 一定不能听主窗口的按键,知道listwidget的项目正在改变。
  • 正确的快捷方式是添加Qaction,然后将快捷方式与此操作相关联。为什么?如果stack中的小部件需要接收“输入”键事件(例如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);
}

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

修改
如果焦点位于列表小部件上,则使用键盘更改列表中的行将触发信号。

答案 1 :(得分: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;
...

为:

mymainwindow.h

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

mymainwindow.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保护或任何其他参数。

但实际上,这听起来像是一种腥味的设计。