带有自定义小部件的 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();
然后将每个 QPushButton
的 clicked()
信号与该信号连接。此代码位于小部件 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。
我试过了,效果很好,解决方法很简单。
我有一个包含 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();
然后将每个 QPushButton
的 clicked()
信号与该信号连接。此代码位于小部件 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。 我试过了,效果很好,解决方法很简单。