在 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 项目的延迟[关闭]的主要内容,如果未能解决你的问题,请参考以下文章