QListWidget 选择后如何显示正确的 QStackedWidget 页面

How to show proper QStackedWidget page after QListWidget selection

我有 1 QListWidget1 QStackedWidgetQstackedWidgetQListWidget 上的条目 select 之后显示三个不同的小部件。

问题:因为我select第一选择没有任何反应,如果我select第二选择也没有反应,但是当我select 最后选择我看到的widget 就QStackedWidget。此小部件不属于第三个小部件,但它属于第一个小部件。

[QListWidget::currentRowChanged(C++ - QListWidget select first item) 的信号似乎没有被正确触发。为什么会这样?基本上似乎只触发最后一个选择而不是所有其他选择。

下面的代码片段:

1 解决方案: 部分有效,因为在三个选项中我只能看到 QStackedWidget 上显示的最后一个 QWidget

OptionsDialog::OptionsDialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::OptionsDialog)
{
    ui->setupUi(this);

    mVesPos = new VesselPosSystemWidget;
    mSonar = new SonarForm;
    mOutput = new OutputForm;
    ui->stackedWidget->addWidget(mVesPos);
    ui->stackedWidget->addWidget(mSonar);
    ui->stackedWidget->addWidget(mOutput);

    ui->horizontalLayout->addWidget(ui->stackedWidget);
    setLayout(ui->horizontalLayout);


    QObject::connect(ui->listWidget, &QListWidget::currentRowChanged,
            ui->stackedWidget, &QStackedWidget::setCurrentIndex);
}

OptionsDialog::~OptionsDialog()
{
    delete ui;
}

2 解决方案: 部分有效,因为在三个选项中我只能看到 QStackedWidget 上显示的最后一个 QWidget。此解决方案取自 official documentation of QStackedWidget:

OptionsDialog::OptionsDialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::OptionsDialog)
{
    ui->setupUi(this);

    mVesPos = new VesselPosSystemWidget;
    mSonar = new SonarForm;
    mOutput = new OutputForm;
    ui->stackedWidget->addWidget(mVesPos);
    ui->stackedWidget->addWidget(mSonar);
    ui->stackedWidget->addWidget(mOutput);

    ui->horizontalLayout->addWidget(ui->stackedWidget);
    setLayout(ui->horizontalLayout);


    connect(ui->listWidget, QOverload<int>::of(&QListWidget::currentRowChanged),
        ui->stackedWidget, &QStackedWidget::setCurrentIndex);

}

OptionsDialog::~OptionsDialog()
{
    delete ui;
}

3 解决方案: 完全相同的效果,仅显示第三个 QWidget

OptionsDialog::OptionsDialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::OptionsDialog)
{
    ui->setupUi(this);

    mVesPos = new VesselPosSystemWidget;
    mSonar = new SonarForm;
    mOutput = new OutputForm;
    ui->stackedWidget->addWidget(mVesPos);
    ui->stackedWidget->addWidget(mSonar);
    ui->stackedWidget->addWidget(mOutput);

    ui->horizontalLayout->addWidget(ui->stackedWidget);
    setLayout(ui->horizontalLayout);


    connect(ui->listWidget, &QListWidget::currentRowChanged,
        [=](int index) { on_listWidget_currentRowChanged(index); });


}

OptionsDialog::~OptionsDialog()
{
    delete ui;
}

void OptionsDialog::on_listWidget_currentRowChanged(int currentRow)
{
    ui->stackedWidget->setCurrentIndex(currentRow);
}

我不知道还有什么可以尝试在 QListWidget 中选择项目后切换 .ui 表单。有什么我想念的吗?我尝试了所有可能的 connect 组合,但尽管如此我只能显示第三个选择。

我希望这对其他用户有用。我找到了解决这个问题的方法。这并不容易,需要深入阅读官方文档。基本上发生的事情是,当我试图在 QlistWidget 上 select 正确的 QWidget 时,selection 错误地变成了不正确的形式。我试过

qDebug() << ui->stackedWidget->addWidget(mSonar);
qDebug() << ui->stackedWidget->addWidget(mOutput);

并且正在获取索引 3、4、5。这解释了为什么我只看到最后一个索引。 现在,在长时间深入阅读文档之后,我发现了 QStackedWidget::insertWidget 与所有可能的 QWidget 的关系,你想 link 到堆栈。它基本上 link 在您传递的内容 QWidgets 的精确条件下将所有视图发送到表单。例如,如果你想 link 一个 QDialogQStackedWidget 这是不允许的,因为 QStackedWidgets 继承 QWidgets。 因此,解决方案是从一开始就插入正确的小部件,手动传递正确的索引(在我的例子中)。

代码解:

OptionsDialog::OptionsDialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::OptionsDialog)
{
    ui->setupUi(this);
    mVesPos = new VesselPosSystemWidget;
    mSonar = new SonarForm;
    mOutput = new OutputForm;
    ui->stackedWidget->insertWidget(0, mVesPos);
    ui->stackedWidget->insertWidget(1, mSonar);
    ui->stackedWidget->insertWidget(2, mOutput);

    // This is how to link the choice according to the latest signals notation
    connect(ui->listWidget, &QListWidget::currentRowChanged,
            ui->stackedWidget, &QStackedWidget::setCurrentIndex);
}

可以找到函数here and you can actually see, if you read carefully how the inheritance works. So again int QStackedWidget::insertWidget(int index, QWidget *widget) from official documentation解决了问题。我希望这可以解决其他用户的问题。 :)