• 嵌入式Qt-实现两个窗口的切换


    之前的文章,分别有介绍过使用Qt程序实现一个时钟和一个秒表,本篇,来将这两个功能整合在一起,实现两个页面的随意切换,并且两个页面能独立运行,互不影响。

    先来看下最终的效果,通过左侧的两个按钮,实现两个页面的切换。

    1 Qt堆栈窗口

    本篇的页面切换功能,是利用Qt的QStackedWidget实现的。

    1.1QStackedWidget

    QStackedWidget 类提供了多页面切换的布局,一次只能显示一个界面。

    1.2 基础模板

    对于QStackedWidget的使用,可以先参考下面这个模板,配合QLabel来控制页面的切换:

    #include "stackdlg.h"
    #include 
    
    StackDlg::StackDlg(QWidget *parent)
        : QDialog(parent)
    {
        setWindowTitle(tr("StackedWidget"));
    
        list = new QListWidget(this); //创建ListWidge
        list->insertItem(0, tr("Window1")); //ListWidge中添加Item
        list->insertItem(1, tr("Window2")); //ListWidge中添加Item
        list->insertItem(2, tr("Window3")); //ListWidge中添加Item
    
        stack = new QStackedWidget(this); //创建StackedWidget
        label1 = new QLabel(tr("WindowTest1"));
        label2 = new QLabel(tr("WindowTest2"));
        label3 = new QLabel(tr("WindowTest3"));
        stack->addWidget(label1); //StackedWidget中添加窗口1
        stack->addWidget(label2); //StackedWidget中添加窗口2
        stack->addWidget(label3); //StackedWidget中添加窗口3
    
        QHBoxLayout *mainLayout = new QHBoxLayout(this); //创建竖直布局器
        mainLayout->setMargin(5);
        mainLayout->setSpacing(5);
        mainLayout->addWidget(list);                      //放入ListWidge
        mainLayout->addWidget(stack,0, Qt::AlignHCenter); //放入StackedWidget
        mainLayout->setStretchFactor(list, 1);  //ListWidge的伸缩尺度是1
        mainLayout->setStretchFactor(stack, 3); //StackedWidget的伸缩尺度是3
    
        // ListWidge的行状态变化时,切换对应的StackedWidget显示
        connect(list, SIGNAL(currentRowChanged(int)), stack, SLOT(setCurrentIndex(int)));
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    该代码的运行效果如下:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SwJ6IO7N-1659970086705)(https://xxpcb-1259761082.cos.ap-shanghai.myqcloud.com/pic2/qt-arm/4-stackwidget/2.png)]

    本篇就在这个模板的基础上,将Qt时钟程序和Qt秒表程序移植过来。

    2 移植时钟与秒表程序

    2.1 时钟程序移植

    将之前这篇中的程序作为一个独立的窗口移植到本篇的程序中:嵌入式Qt-动手编写并运行自己的第1个ARM-Qt程序

    移植步骤:

    • Qt Creator中,堆栈窗口基础工程的基础上,点文件菜单,再点新建文件或项目,新建一个C++类,名字可取clockwidget

    • 将Qt时钟的程序复制过来,代码基本不需要修改,只需要把类名换成ClockWidget即可

    例如其构造函数如下:

    ClockWidget::ClockWidget(QWidget *parent) : QWidget(parent)
    {
        QTimer *timer = new QTimer(this);
        connect(timer, SIGNAL(timeout()), this, SLOT(update()));
        timer->start(1000);
    
        setWindowTitle(tr("Clock"));
        setMinimumSize(200, 200); //设置最小尺寸
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    2.2 秒表程序移植

    将之前这篇中的程序作为一个独立的窗口移植到本篇的程序中:嵌入式Qt-做一个秒表

    秒表这个Qt程序,用到了Qt Creator的图形页面设计,因此要主要移植的不同之处。

    移植步骤:

    • Qt Creator中,堆栈窗口基础工程的基础上,点文件菜单,再点新建文件或项目,新建一个C++类,名字可取TimerWidget

    • 将ui文件也拷贝过来,在工程中,通过添加现有文件的方式,将ui文件添加进工程

    • 另外,可以将移植过来的ui文件,更名为TimerWidget.ui。需注意的是,修改了文件名后,还需要将ui文件以文本的形式打开,修改对应的类名为TimerWidget,要包含的头文件也改名为ui_TimerWidget.h

    移植后的构造函数如下:

    #include "timerwidget.h"
    #include "ui_TimerWidget.h"
    #include
    #pragma execution_character_set("utf-8")
    
    TimerWidget::TimerWidget(QWidget *parent) : QWidget(parent), ui(new Ui::TimerWidget)
    {
        ui->setupUi(this);
        connect(&timer, SIGNAL(timeout()), this, SLOT(timeout_slot()));
        connect(&timer, SIGNAL(timeout()), this, SLOT(update()));
        connect(ui->Btn_Reset, SIGNAL(clicked()), this, SLOT(update()));
    
        time.setHMS(0,0,0,0);
        ui->Txt_ShowTime->setText("00:00:00");
    
        ui->Btn_Start->setChecked(false);
        ui->Btn_Reset->setEnabled(false);
        ui->Btn_Hit->setEnabled(false);
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    注意头文件包含的是ui_TimerWidget.h,构造函数继承的ui也是Ui::TimerWidget

    2.3 主程序框架

    移植好Qt时钟程序和Qt秒表程序后,就可以将这两个功能加入到堆栈窗口中了。

    注意,下面的页面切换,我改用两个QPushButton来实现Qt时钟和Qt秒表的页面切换,并使用QGridLayout进行布局,使得两个按钮位于整个界面的左侧。

    StackDlg::StackDlg(QWidget *parent)
        : QDialog(parent)
    {
        setWindowTitle(tr("StackedWidget"));
        setMinimumSize(800, 480);
        qDebug("Hello");
    
        QPushButton *pClockButton = new QPushButton("时\n钟", this);
        QPushButton *pTimerButton = new QPushButton("秒\n表", this);
        pClockButton->setFixedSize(QSize(80,200));
        pClockButton->setFont(QFont("Times", 20));
        pTimerButton->setFixedSize(QSize(80,200));
        pTimerButton->setFont(QFont("Times", 20));
    
        pStack = new QStackedWidget(this);
        ClockWidget *pClockWidget = new ClockWidget();
        TimerWidget *pTimerWidget = new TimerWidget();
        pStack->addWidget(pClockWidget);
        pStack->addWidget(pTimerWidget);
    
        QGridLayout *mainLayout = new QGridLayout(this);
        mainLayout->addWidget(pClockButton, 0, 0, Qt::AlignCenter);
        mainLayout->addWidget(pTimerButton, 1, 0, Qt::AlignCenter);
        mainLayout->addWidget(pStack, 0, 1, 2, 1);
    
        mainLayout->setContentsMargins(10,10,1,1);
        mainLayout->setColumnStretch(1, 10);
        mainLayout->setRowStretch(1, 1);
    
        connect(pClockButton, SIGNAL(clicked()), this, SLOT(showClock()));
        connect(pTimerButton, SIGNAL(clicked()), this, SLOT(showTimer()));
    }
    
    void StackDlg::showClock()
    {
        qDebug("%s", __func__);
        pStack->setCurrentIndex(0);
    }
    void StackDlg::showTimer()
    {
        qDebug("%s", __func__);
        pStack->setCurrentIndex(1);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    另外需要注意的是,Qt的信号和槽机制,需要信号和槽函数的参数一致或信号的参数多于槽的参数,而按钮按下没有参数,但切换堆栈页面需要一个参数(索引号,指示要展示第几个页面),因此不能直接使用pStack的setCurrentIndex作为槽函数,需要自己再封装一层,分别写两个按钮按下时的槽函数。

    3 测试

    将代码在Windows上编译运行ok后,再将源码复制到Ububtu中进行交叉编译,具体的编译过程可参考之前的文章:嵌入式Qt-动手编写并运行自己的第1个ARM-Qt程序

    然后将编译后的程序复制到Linux板子中运行,运行效果如下:
    https://www.bilibili.com/video/BV1RB4y147s7
    在这里插入图片描述

    可以看到Qt时钟和Qt秒表这两个页面可以随意切换,并且两个页面独立运行,某个页面被隐藏显示时,其计时功能仍在运行,再次将页面切换回来,计时时间也是对的。

    4 总结

    本篇介绍了介绍了QStackedWidget的使用,通过这个类,实现了Qt时钟和Qt秒表这两个页面可以随意切换。

  • 相关阅读:
    PCL点云库 点云拼接
    0基础学习VR全景平台篇第119篇:利用蒙版航拍补天 - PS教程
    cadence virtuoso layout drc error
    开源操作系统大全
    迅为RK3568开发板Android12 系统功能测试-有线网测试
    如何让ESP8266板子像APP开发一样方便
    webpack 与 grunt、gulp 的不同?
    ​​【项目实战】犬只牵绳智能识别:源码详细解读与部署步骤
    解析vue.config.js文件
    降噪耳机哪个牌子好又平价?降噪耳机性价比排行
  • 原文地址:https://blog.csdn.net/hbsyaaa/article/details/126237921