У меня есть 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);
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);
}
}
Других решений пока нет …