Как показать правильные GUI на QStackedWidget в зависимости от выбора на QListWidget - PullRequest
0 голосов
/ 22 марта 2020

Как правильно отобразить правильный пользовательский интерфейс на QStacked Widget в зависимости от выбора на QListWidget?

Ниже у меня есть QDialog, который содержит:

1 QListWidget

1 QStackedWidget

stack

В зависимости от выбранного варианта списка, например, Система позиционирования судна или Выход, интерфейс должен выглядеть следующим образом, но проблема в том, что к сожалению QStacked Widget в настоящее время не меняет QWidgets, так как я выбираю QListWidgets, на самом деле ничего не показывает. Минимальный проверяемый пример можно найти здесь . Просто клонируйте его, и оно будет работать:

output

Ниже кода:

optionsdialog.h

#include <QDialog>
#include "vesselpossystemwidget.h"
#include "outputdialog.h"
#include "sonarsystem.h"
namespace Ui {
class OptionsDialog;
}

class OptionsDialog : public QDialog
{
    Q_OBJECT
public:
    explicit OptionsDialog(QWidget *parent = nullptr);
    ~OptionsDialog();

private:
    Ui::OptionsDialog *ui;
    VesselPosSystemWidget *mVesPos;
    OutputDialog *mOutput;
    SonarSystem *mSonar;
};

#endif // OPTIONSDIALOG_H

optionsdialog.h

#include "optionsdialog.h"
#include "ui_optionsdialog.h"

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

      case 0:
        // Go to positioning system
        mVesPos = new VesselPosSystemWidget();
        mVesPos->show();
        break;
      case 1:
        // Go to sonar set up...
        mSonar = new SonarSystem();
        mSonar->show();
        break;
      case 2:
        // Go to output
        mOutput = new OutputDialog();
        mOutput->show();
        break;
      default:
        break;
    }
}

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

vesselposwidget.h

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class VesselPosSystemWidget; }
QT_END_NAMESPACE

class VesselPosSystemWidget : public QWidget
{
    Q_OBJECT

public:
    VesselPosSystemWidget(QWidget *parent = nullptr);
    ~VesselPosSystemWidget();

private:
    Ui::VesselPosSystemWidget *ui;
};
#endif // VESSELPOSSYSTEMWIDGET_H

vesselposwidget. cpp

#include "vesselpossystemwidget.h"
#include "ui_vesselpossystemwidget.h"

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

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

output.h

#include <QDialog>

namespace Ui {
class OutputDialog;
}

class OutputDialog : public QDialog
{
    Q_OBJECT

public:
    explicit OutputDialog(QWidget *parent = nullptr);
    ~OutputDialog();

private:
    Ui::OutputDialog *ui;
};

#endif // OUTPUTDIALOG_H

output. cpp

#include "outputdialog.h"
#include "ui_outputdialog.h"

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

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

Что я уже сделали:

Я изучаю возможность использования QStacked Widget, так как я не очень знаком с ним и хотел попрактиковаться с базовым c примером. Я исследовал этот источник , а также этот

Также из того же источника есть больше документации, которую я прочитал. Однако я не был полностью в состоянии ясно понять использование этого конкретного виджета.

В дополнение к этому я попробовал switch - case l oop, как я показал выше в коде, но я не уверен, почему это не работает

Кто-нибудь может дать несколько советов о том, как правильно отображать правильный пользовательский интерфейс на QStacked Widget в зависимости от выбора QListWidget? Любое направление для решения этой проблемы приветствуется.

1 Ответ

3 голосов
/ 22 марта 2020

A QStackedWidget - это контейнерный виджет для нескольких дочерних виджетов, который показывает только один из них одновременно.

Следовательно, все дочерние виджеты должны быть добавлены одновременно.

currentIndex может использоваться для контроля того, какой из них должен быть видим в данный момент.

A минимальный воспроизводимый пример , чтобы продемонстрировать это - testQStackedWidgetMin.cc:

// Qt header:
#include <QtWidgets>

// main application
int main(int argc, char **argv)
{
  qDebug() << "Qt Version:" << QT_VERSION_STR;
  QApplication app(argc, argv);
  // setup GUI
  QWidget qWinMain;
  QHBoxLayout qHBox;
  QListWidget qList;
  qList.addItem(QString::fromUtf8("Config. 1"));
  qList.addItem(QString::fromUtf8("Config. 2"));
  qList.addItem(QString::fromUtf8("Output"));
  qHBox.addWidget(&qList);
  QStackedWidget qStack;
  QLabel qConfig1(QString::fromUtf8("<b>Config Page 1</b>"));
  qStack.addWidget(&qConfig1);
  QLabel qConfig2(QString::fromUtf8("<b>Config Page 2</b>"));
  qStack.addWidget(&qConfig2);
  QLabel qOutput(QString::fromUtf8("<b>Output Page</b>"));
  qStack.addWidget(&qOutput);
  qHBox.addWidget(&qStack, 1);
  qWinMain.setLayout(&qHBox);
  qWinMain.show();
  // install signal handlers
  QObject::connect(&qList, &QListWidget::currentRowChanged,
    &qStack, &QStackedWidget::setCurrentIndex);
  // runtime loop
  return app.exec();
}

Выход:

Snapshot of testQStackedWidgetMin

Примечание:

Одним из основных утверждений этого образца является сигнал соединение:

  QObject::connect(&qList, &QListWidget::currentRowChanged,
    &qStack, &QStackedWidget::setCurrentIndex);

Сигнал QListWidget :: currentRowChanged сигнала QListWidget qList подключен к QStackedWidget :: setCurrentIndex () функции QStackedWidget qStack. Это ответственно за обновление qStack для любого (интерактивного) изменения строки в qList.


Не столь минимальная выборка в соответствии с намерением OP - testQStackedWidget.cc:

// Qt header:
#include <QtWidgets>

class Config1: public QWidget {
  private:
    // GUI
    QVBoxLayout _qVBox;
    QLabel _qLbl;

  public:
    // constructor.
    Config1();
    // destructor.
    virtual ~Config1() = default;
    // disabled:
    Config1(const Config1&) = delete;
    Config1& operator=(const Config1&) = delete;
};


Config1::Config1(): QWidget()
{
  // setup GUI
  _qLbl.setText(QString::fromUtf8("<b>Config Page 1</b>"));
  _qVBox.addWidget(&_qLbl);
  setLayout(&_qVBox);
}

class Config2: public QWidget {
  private:
    // GUI
    QVBoxLayout _qVBox;
    QLabel _qLbl;

  public:
    // constructor.
    Config2();
    // destructor.
    virtual ~Config2() = default;
    // disabled:
    Config2(const Config2&) = delete;
    Config2& operator=(const Config2&) = delete;
};

Config2::Config2(): QWidget()
{
  _qLbl.setText(QString::fromUtf8("<b>Config Page 2</b>"));
  _qVBox.addWidget(&_qLbl);
  setLayout(&_qVBox);
}

class Output: public QWidget {
  private:
    // GUI
    QVBoxLayout _qVBox;
    QLabel _qLbl;

  public:
    // constructor.
    Output();
    // destructor.
    virtual ~Output() = default;
    // disabled:
    Output(const Output&) = delete;
    Output& operator=(const Output&) = delete;
};

Output::Output(): QWidget()
{
  _qLbl.setText(QString::fromUtf8("<b>Output Page</b>"));
  _qVBox.addWidget(&_qLbl);
  setLayout(&_qVBox);
}

class OptionDialog: public QDialog {
  private:
    // GUI
    QHBoxLayout _qHBox;
    QListWidget _qList;
    QStackedWidget _qStack;
    Config1 _qConfig1;
    Config2 _qConfig2;
    Output _qOutput;

  public:
    // constructor.
    OptionDialog();
    // destructor.
    virtual ~OptionDialog() = default;
    // disabled:
    OptionDialog(const OptionDialog&) = delete;
    OptionDialog& operator=(const OptionDialog&) = delete;
};

OptionDialog::OptionDialog(): QDialog()
{
  // setup GUI
  _qList.addItem(QString::fromUtf8("Config. 1"));
  _qList.addItem(QString::fromUtf8("Config. 2"));
  _qList.addItem(QString::fromUtf8("Output"));
  _qHBox.addWidget(&_qList);
  _qStack.addWidget(&_qConfig1);
  _qStack.addWidget(&_qConfig2);
  _qStack.addWidget(&_qOutput);
  _qHBox.addWidget(&_qStack, 1);
  setLayout(&_qHBox);
  // install signal handlers
  QObject::connect(&_qList, &QListWidget::currentRowChanged,
    &_qStack, &QStackedWidget::setCurrentIndex);
}

// main application
int main(int argc, char **argv)
{
  qDebug() << "Qt Version:" << QT_VERSION_STR;
  QApplication app(argc, argv);
  // setup GUI
  OptionDialog qDlgOpt;
  qDlgOpt.show();
  // runtime loop
  return app.exec();
}

Вывод:

Snapshot of testQStackedWidget


CMakeLists.txt, который я использовал для создания решения VisualStudio:

project(QStackedWidget)

cmake_minimum_required(VERSION 3.10.0)

set_property(GLOBAL PROPERTY USE_FOLDERS ON)
#set(CMAKE_CXX_STANDARD 17)
#set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

find_package(Qt5Widgets CONFIG REQUIRED)

include_directories("${CMAKE_SOURCE_DIR}")

add_executable(testQStackedWidgetMin
  testQStackedWidgetMin.cc)

target_link_libraries(testQStackedWidgetMin
  Qt5::Widgets)

add_executable(testQStackedWidget
  testQStackedWidget.cc)

target_link_libraries(testQStackedWidget
  Qt5::Widgets)
...