QTabWidget的自定义切换行为

时间:2017-11-07 13:29:37

标签: c++ qt

问题

我想制作一个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:更好的标题

0 个答案:

没有答案