带有自定义小部件的 QListWidget - 不触发项目点击信号

QListWidget with custom widgets - not triggering itemClicked signal

本文关键字:项目 信号 自定义 小部 QListWidget      更新时间:2023-10-16

我有一个listwidgetitem,它有一个自定义小部件(step_widget),其中包含3个QPushButtons和一个QLabel。 当我按下小部件中的一个按钮时,它不会触发itemClicked,我需要查看单击的列表小部件的索引。如果我点击QLabel,信号被触发,我能够获得索引。按下其中一个按钮时如何触发信号?为什么不触发?

QListWidgetItem *item = new QListWidgetItem();
stepWidget *step_widget = new stepWidget();
ui->listWidget->addItem(item);
ui->listWidget->setItemWidget(item,step_widget);

不会发出itemClicked()信号,因为QPushButton消耗单击事件。
我找到了最简单的解决方案。
首先,在您的类中stepWidget添加一个在单击任何QPushButton时将发出的信号,例如:

signals:
void widgetClicked();

然后将每个QPushButtonclicked()信号与该信号连接起来。此代码位于小部件的构造函数中stepWidget

connect(ui->pushButton1, &QPushButton::clicked, this, &stepWidget::widgetClicked);
connect(ui->pushButton2, &QPushButton::clicked, this, &stepWidget::widgetClicked);
connect(ui->pushButton3, &QPushButton::clicked, this, &stepWidget::widgetClicked);

为了测试它,我在MainWindow类中的QListWidget中添加了 10 个小部件。您必须将该信号连接到一个插槽(在本例中,我使用 C++11 Lambda 函数,但您可以创建一个插槽,这很好),您可以在其中将当前项目建立为小部件下的项目。此代码位于MainWindow的构造函数中:

for (int i = 0; i < 10; ++i) {
QListWidgetItem *item = new QListWidgetItem;
stepWidget *step_Widget = new stepWidget;
ui->listWidget->addItem(item);
ui->listWidget->setItemWidget(item, step_Widget);
connect(step_Widget, &stepWidget::widgetClicked, [=]() {
ui->listWidget->setCurrentItem(item);
});
}

现在,这不会发出itemClicked()信号,因为用户未单击该项目。但是我建议您连接信号currentRowChanged(),因为它将使用此代码发出,并且它的优点是它允许您直接获取行。显然,一旦你有了行,你就可以获得项目和小部件。
但是,此过程有一个不方便,即即使用户使用键盘选择一行或当用户在QListWidget上按下并滑动鼠标而不释放它时,也会发出currentRowChanged()信号。
例如,解决方法可能是使用标志作为始终falseMainWindow类的属性,除非在此连接期间:

connect(ste_pWidget, &stepWidget ::widgetClicked, [=]() {
buttonPressed = true;
ui->listWidget->setCurrentItem(item);
buttonPressed = false;
});

然后你必须操纵来自QListWidget的两个信号:clicked()currentRowChanged()。我选择clicked()而不是itemClicked()因为它几乎可以直接访问该行:

void MainWindow::on_listWidget_clicked(const QModelIndex &index)
{
ui->statusBar->showMessage(tr("Row clicked: %1").arg(index.row()), 1000);
}
void MainWindow::on_listWidget_currentRowChanged(int currentRow)
{
if (buttonPressed) {
ui->statusBar->showMessage(tr("Row clicked: %1").arg(currentRow), 1000);
}
}

你可以简单地做的是,让你的qPushbutton到qlabel,然后qPushButton将变得可点击。 然后,您可以覆盖此方法:- on_listWidget_itemClicked(QListWidgetItem *item)以双击qpushbutton。 我试过了,它工作得很好,它非常简单的解决方法。