如何根据 QListWidget 上的选择在 QStackedWidget 上显示正确的 GUI
How to show the correct GUI on a QStackedWidget depending on the choice on a QListWidget
如何根据 QListWidget
上的选择在 QStacked Widget
上正确显示正确的用户界面?
下面我有一个 QDialog
包含:
1 QListWidget
1 QStackedWidget
根据列表的 selected 选择,例如,Vessel Position System 或 Output,界面应如下所示,但问题是不幸的是 QStacked Widget
目前没有改变 QWidgets
因为我 select QListWidgets
实际上没有显示任何东西。 A Minimal Verifiable Example can be found here。只需克隆它即可运行:
代码下方:
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
的可能性,因为我对它不是很熟悉并且想通过一个基本示例进行练习。我在调查 and also this one
我还从 same 源中阅读了更多文档。但是我并不能完全清楚地理解这个特定小部件的使用。
除此之外,我尝试了一个 switch - case
循环,正如我在上面的代码中所示,但我不确定为什么它不起作用
谁能提供一些指导,说明如何根据 QListWidget
上的选择在 QStacked Widget
上正确显示正确的用户界面?解决此问题的任何方向表示赞赏。
QStackedWidget 是一个容器小部件,用于多个子小部件,一次只显示其中一个。
因此,应立即添加所有子窗口小部件。
currentIndex
可用于控制其中哪些当前应该可见。
A minimal reproducible example 来证明这一点 – 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();
}
输出:
注:
这个样本的基本语句之一是信号槽连接:
QObject::connect(&qList, &QListWidget::currentRowChanged,
&qStack, &QStackedWidget::setCurrentIndex);
QStackedWidget qStack
的QListWidget::currentRowChanged signal of the QListWidget qList
is connected to the QStackedWidget::setCurrentIndex()函数。
这负责为 qList
.
中的任何(交互式)行更改更新 qStack
根据 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();
}
输出:
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)
如何根据 QListWidget
上的选择在 QStacked Widget
上正确显示正确的用户界面?
下面我有一个 QDialog
包含:
1 QListWidget
1 QStackedWidget
根据列表的 selected 选择,例如,Vessel Position System 或 Output,界面应如下所示,但问题是不幸的是 QStacked Widget
目前没有改变 QWidgets
因为我 select QListWidgets
实际上没有显示任何东西。 A Minimal Verifiable Example can be found here。只需克隆它即可运行:
代码下方:
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
的可能性,因为我对它不是很熟悉并且想通过一个基本示例进行练习。我在调查
我还从 same 源中阅读了更多文档。但是我并不能完全清楚地理解这个特定小部件的使用。
除此之外,我尝试了一个 switch - case
循环,正如我在上面的代码中所示,但我不确定为什么它不起作用
谁能提供一些指导,说明如何根据 QListWidget
上的选择在 QStacked Widget
上正确显示正确的用户界面?解决此问题的任何方向表示赞赏。
QStackedWidget 是一个容器小部件,用于多个子小部件,一次只显示其中一个。
因此,应立即添加所有子窗口小部件。
currentIndex
可用于控制其中哪些当前应该可见。
A minimal reproducible example 来证明这一点 – 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();
}
输出:
注:
这个样本的基本语句之一是信号槽连接:
QObject::connect(&qList, &QListWidget::currentRowChanged,
&qStack, &QStackedWidget::setCurrentIndex);
QStackedWidget qStack
的QListWidget::currentRowChanged signal of the QListWidget qList
is connected to the QStackedWidget::setCurrentIndex()函数。
这负责为 qList
.
qStack
根据 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();
}
输出:
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)