我想制作一个QTabWidget,对于某些标签,切换到子QStackedWidget的同一页面而不是每个标签的单个页面。这是因为在多个选项卡上需要一些列表(但在其他选项卡上则不需要,所以我不能将它放在选项卡上方),但我只想拥有一个列表对象,所以只填充一次,不选项卡之间的同步等。
摘要示例:
GUI导入一些数据
用户可以选择多个工作流程(标签)进行选择
作图
频率分析
出口
统计
在所有选项卡上,GUI需要一种通道选择器,因此数据中的可用通道列表和所选通道列表。
在绘图选项卡上,还需要选择绘图的x轴。
统计数据在我的例子中是奇数,在此选项卡上只显示信息,这是自动为所有通道计算的,例如只有一些复选框。
我不使用QTabWidget,而是使用QTabBar和QStackedWidget。这里的问题是,我无法实现QTabWidget的外观,因此在QStackedWidget的页面内容周围有一个选定选项卡的框架(目前我并不关心格式化标签本身):
{{3}}
现在,我的工作方式是使用QTabWidget,从包含QStackedWidget断开包含QTabBar的currentChanged()信号,并实现我自己的插槽在QStackedWidget中的页面之间切换(参见代码示例)。 / p>
我这样做的方式似乎有点复杂而且不是很漂亮,因为我无法直接在QTabWidget中获取QStackedWidget的指针。
以下是图片中两种变体的示例代码:
main.cpp(两个例子都相同):
#include <QApplication>
#include "mainwindow.h"
int main(int argc, char **argv)
{
QApplication app(argc, argv);
MainWindow mw;
mw.show();
return app.exec();
}
mainwindow.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QTabBar>
#include <QTabWidget>
#include <QStackedWidget>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
// constructor
explicit MainWindow(QWidget *parent = 0);
private:
void switchTab1(int index);
void switchTab2(int index);
QTabWidget *tabwidget1_;
QTabBar *tabwidget2_;
QStackedWidget *stack1_;
QStackedWidget *stack2_;
};
#endif // MAINWINDOW_H
mainwindow.cpp:
#include <QListWidget>
#include <QPushButton>
#include <QLayout>
#include "mainwindow.h"
// constructor
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent)
{
//LEFT
QWidget *listTab1 = new QWidget;
QVBoxLayout *listTab1Layout = new QVBoxLayout;
listTab1Layout->addWidget(new QListWidget);
listTab1Layout->addWidget(new QListWidget);
listTab1->setLayout(listTab1Layout);
QWidget *buttonTab1 = new QWidget;
QVBoxLayout *buttonTab1Layout = new QVBoxLayout;
buttonTab1Layout->addWidget(new QPushButton);
buttonTab1Layout->addWidget(new QPushButton);
buttonTab1Layout->addStretch();
buttonTab1->setLayout(buttonTab1Layout);
tabwidget1_ = new QTabWidget;
tabwidget1_->addTab(listTab1,"tab1");
tabwidget1_->addTab(new QWidget,"tab2");
tabwidget1_->addTab(new QWidget,"tab3");
tabwidget1_->addTab(buttonTab1,"tab4");
// extracts the stacked widget, parentWidget() returns QObject,
// so it needs to be casted to QStackedWidget
stack1_ = qobject_cast<QStackedWidget*>(tabwidget1_->widget(0)->parentWidget());
// extract the tabbar
QTabBar *tabbar = tabwidget1_->tabBar();
// disconnects the switching of tabs, so I can implement my own function
disconnect(tabbar,&QTabBar::currentChanged,0,0);
// reconnect to manipulate the switching
connect(tabbar,&QTabBar::currentChanged,this,&MainWindow::switchTab1);
// RIGHT
QWidget *listTab2 = new QWidget;
QVBoxLayout *listTab2Layout = new QVBoxLayout;
listTab2Layout->addWidget(new QListWidget);
listTab2Layout->addWidget(new QListWidget);
listTab2->setLayout(listTab2Layout);
QWidget *buttonTab2 = new QWidget;
QVBoxLayout *buttonTab2Layout = new QVBoxLayout;
buttonTab2Layout->addWidget(new QPushButton);
buttonTab2Layout->addWidget(new QPushButton);
buttonTab2Layout->addStretch();
buttonTab2->setLayout(buttonTab2Layout);
tabwidget2_ = new QTabBar;
tabwidget2_->addTab("tab1");
tabwidget2_->addTab("tab2");
tabwidget2_->addTab("tab3");
tabwidget2_->addTab("tab4");
stack2_ = new QStackedWidget;
stack2_->addWidget(listTab2);
stack2_->addWidget(buttonTab2);
connect(tabwidget2_,&QTabBar::currentChanged,this,&MainWindow::switchTab2);
QVBoxLayout *rightLayout = new QVBoxLayout;
rightLayout->addWidget(tabwidget2_);
rightLayout->addWidget(stack2_);
// ADD TO MAIN
QWidget *mainWidget = new QWidget;
QHBoxLayout *mainLayout = new QHBoxLayout;
mainLayout->addWidget(tabwidget1_);
mainLayout->addLayout(rightLayout);
mainWidget->setLayout(mainLayout);
setCentralWidget(mainWidget);
}
void MainWindow::switchTab1(int index)
{
// stack_->setCurrentIndex(index);
// return;
switch (index) {
case 0:
case 1:
case 2:
stack1_->setCurrentIndex(0);
break;
case 3:
stack1_->setCurrentIndex(3);
break;
}
emit tabwidget1_->currentChanged(index);
}
void MainWindow::switchTab2(int index)
{
// stack_->setCurrentIndex(index);
// return;
switch (index) {
case 0:
case 1:
case 2:
stack2_->setCurrentIndex(0);
break;
case 3:
stack2_->setCurrentIndex(1);
break;
}
}
您是否知道更好的方法来实现理想的行为?
或者你会推荐一种不同的方式来创建非常相似的标签吗?
编辑1:更好的标题