qt中显示QStackedWidget项的延迟



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

井:

  • 您正在重写QMainWindow::keyPressEvent(QKeyEvent *event),并完全忽略默认实现
  • Qobject::每次按键连接都是错误的。你似乎对它的作用有自己的解释阅读文档
  • 必须不听主窗口的按键才能知道列表小部件的项目正在更改
  • 正确的快捷方式是添加一个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);
}

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

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

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

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

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

最新更新