-1

I have 1 QListWidget and 1 QStackedWidget. The QstackedWidget has three different widgets to be shown after selecting the entriesd on the QListWidget.

The problem: as I select the first choice nothing happens and nothing happens if I select the second choice, but when I select the last choice I see the widget on the QStackedWidget. This widget does not appartain to the third widget but it appartain to the first widget.

Signals of [QListWidget::currentRowChanged(C++ - QListWidget select first item) does not seem to be triggered correctly. Why is that happening? Basically seems to be triggered only the last choice instead all the others.

Below the snippet of code:

1 solution: works partially because out of three choices I can only see the last QWidget showing on the 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);


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

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

2 solution: works partially because out of three choices I can only see the last QWidget showing on the QStackedWidget. This solution was taken from 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 solution: same exact effect, only the third QWidget is shown:

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);
}

I don't know what else to try to have the .ui forms switch after selcting the item in the QListWidget. Is there something I am missing? I tried all possible connect combinations but despite that I can only show the third choice.

Emanuele
  • 2,194
  • 6
  • 32
  • 71
  • did you debug your code? put a break point in on_listWidget_currentRowChanged function and check the values of `currentRow`. I don't have a qt setup thus I cannot check your code. – seleciii44 Mar 23 '20 at 16:29
  • thanks for reading the question. Yes I added `qDebug() << currentRow;` and the result is 0. See [here](https://i.imgur.com/QtJDwvz.png). Is this telling you something? – Emanuele Mar 23 '20 at 17:56
  • In addition as you see [here](https://i.imgur.com/ZuOvxIJ.png) the selection of the `QListWidget` entry is correct. But I only see the last `.ui` form appearing on the `QStackedWidget`. I am not sure what is happening. – Emanuele Mar 23 '20 at 18:01
  • ok, let's start from scratch. try to put very basic widgets (label, push button etc.) into stacked widget and change the index. see if it's changing as expected. – seleciii44 Mar 23 '20 at 18:22
  • 1
    @seleciii44, following your advice I started with a basic example e started from there. I found the solution to this question and posted a detailed answer below so that other users can benefit from it. – Emanuele Mar 30 '20 at 14:36
  • Also I don't understand why someone down-voted the question though. It took me a while to extract the most important part of the info from the code and a big effort to try to pose the question in an understandable way. – Emanuele Mar 30 '20 at 14:37
  • 1
    You are very nice and thank you for your time in point me to where the error was! :) – Emanuele Mar 30 '20 at 14:38

1 Answers1

1

I hope this could be useful for other users. I found a solution to this question. It was not easy and it required reading in depth the official documentation. Basically what was happening was that as I tried to select the proper QWidget on the QlistWidget, the selection was erroneously going to the incorrect form. I tried to

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

And was obtaining index 3,4,5. Which explains why I was only seeing the last index. Now after long and in-depth reading of the documentation I found out about QStackedWidget::insertWidget relationships with all possible QWidget you want to link to the stack. It basically linking all the views to the form under the precise condition that what you are passing are QWidgets. So for example if you would like to link a QDialog to the QStackedWidget this is not allowed, because QStackedWidgets inherits QWidgets. Therefore the solution was to insert the correct widget right from the beginning passing the proper index manually (in my case).

Code solution:

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);
}

The function can be found 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 solved the problem. I hope this could solve the problem for other users. :)

Emanuele
  • 2,194
  • 6
  • 32
  • 71