在 qt 中显示 QStackedWidget 项目的延迟[关闭]

Posted

技术标签:

【中文标题】在 qt 中显示 QStackedWidget 项目的延迟[关闭]【英文标题】:delay in displaying QStackedWidget Item in qt [closed] 【发布时间】:2014-01-08 09:29:48 【问题描述】:

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

    

【问题讨论】:

“它需要一些时间,过了一段时间它就可以正常工作了。” -> 你什么意思?如果您的意见有所延迟,什么需要正常工作? 我的意思是 StackedWidget 项目不会根据 listwidget 项目在短时间内改变,比如 30 秒。然后在 30 秒后它正常工作并且所有堆叠的小部件项目都显示出来了。 “StackedWidget 项目没有改变” -> 你的意思是什么改变? 我的意思是当我按下向上键或向下键按钮来更改 Listwidget 项时,StackedWidget 项应该根据它们的 currentIndex 更改。 "connect(list,SIGNAL(currentRowChanged(int)),stack,SLOT(setCurrentIndex(int)));" -> 这个逻辑对我来说似乎很模糊。此外,如果有其他事件正在进行,您的连接不会立即对第一次关闭/启动产生任何影响,因为这是您设置连接的地方。您是否尝试过构造函数中的连接?您也可以尝试 Qt::DirectConnection 作为第五个参数。 【参考方案1】:

嗯:

您正在覆盖QMainWindow::keyPressEvent(QKeyEvent *event) 并完全无视默认实现。 Qobject::connect 在每次按键时都是一个错误。您似乎对它的作用有自己的解释。 阅读文档不得聆听主窗口的按键以了解列表小部件的项目正在发生变化。 快捷方式的正确做法是添加一个Qaction,然后将快捷方式关联到该操作。为什么?如果stack 中的小部件需要接收“Enter”键事件(如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);

不过,这是一场噩梦。

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

【讨论】:

BUt 如何与 key_Up 和 Key_Down 事件交互【参考方案2】:

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

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

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

【讨论】:

我同意您的代码先生。但我只是问如何通过 Key_up 和 Key_down 按下事件进行交互 @user3153003:正如我在回复中所写,在事件处理程序中使用 m_ready 来区分您是否正确连接。 @user3153003:更新了代码。 谢谢您,先生。我会试试这段代码 @user3153003:那不是一个类,而是一个布尔变量...

以上是关于在 qt 中显示 QStackedWidget 项目的延迟[关闭]的主要内容,如果未能解决你的问题,请参考以下文章

Qt - QStackedWidget 使用

Qt--堆栈窗口(QStackedWidget)的使用

pyqt5快速上手基础篇6-QStackedWidget实现导航布局

QT如何实现QStackedWidget界面间的切换

Qt QStackedWidget 调整大小问题

使用 Qt Creator 中设计的自定义小部件将页面动态添加到 QStackedWidget