QListWidget с пользовательскими виджетами — не вызывает сигнал itemClicked

У меня есть listwidgetitem, которые имеют собственный виджет (step_widget), который содержит 3 QPushButton и QLabel.
Когда я нажимаю одну из кнопок в виджете, это не вызывает itemClicked, который мне нужен, чтобы увидеть индекс списка виджетов, который был нажат. Если я нажимаю QLabel, сигнал срабатывает, и я могу получить индекс. Как можно вызвать сигнал, когда нажата одна из кнопок? Почему не срабатывает?

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

0

Решение

itemClicked() сигнал не излучается, потому что QPushButton потребляет событие click.
Есть самое простое решение, которое я нашел.
Во-первых, в вашем классе stepWidget добавить сигнал, который будет издаваться, когда любой QPushButton по щелчку, например:

signals:
void widgetClicked();

Затем подключите clicked() сигнал каждого QPushButton с этим сигналом. Этот код находится в конструкторе виджета 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 виджетов в QListWidget которые проживают в MainWindow учебный класс. Вы должны подключить этот сигнал к слоту (в данном случае я использую лямбда-функцию C ++ 11, но вместо этого вы можете создать слот), где вы устанавливаете текущий элемент как элемент под виджетом. Этот код находится в конструкторе 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() так как он будет выдан с этим кодом, а также имеет то преимущество, что позволяет напрямую получить строку. Если у вас есть строка, вы можете получить элемент и виджет, очевидно.
Однако эта процедура неудобна тем, что currentRowChanged() сигнал будет издаваться, даже когда пользователь выбирает строку с помощью клавиатуры или когда пользователь нажимает и перемещает мышь над QListWidget не отпуская это.
Обходным решением может быть, например, использование флага в качестве атрибута для вашего MainWindow класс, который всегда 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);
}
}
0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]