带有自定义小部件的 QListWidget - 不触发 itemClicked 信号

QListWidget with custom widgets - not triggering itemClicked signal

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

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

itemClicked() 信号未发出,因为 QPushButton 消耗了点击事件。
这是我找到的最简单的解决方案。
首先,在您的 class 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);

为了测试它,我将 10 个小部件添加到位于 MainWindow class 中的 QListWidget。您必须将该信号连接到一个插槽(在这种情况下,我使用 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() 信号。
解决方法可能是,例如,使用标志作为 MainWindow class 的属性,该标志始终为 false,但在此连接期间除外:

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。 我试过了,效果很好,解决方法很简单。