欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > 名人名企 > 基于Qt的app开发第五天

基于Qt的app开发第五天

2025/5/7 0:01:37 来源:https://blog.csdn.net/yxc_71411/article/details/147672007  浏览:    关键词:基于Qt的app开发第五天

写在前面

博主当前是计科大一下学生,大一下的课程设计自命题做一个app,具体功能可见专栏第一篇的需求文档。现在的进度约等于0,不过博主已经把Qt基础知识学完了,具体情况可以看博主的另一篇专栏。这一篇主要记录一下利用Qt中的Stacked Widget控件实现界面切换,弥补前期错误。

当前文件展示

                          

非常惨烈,由于博主在画ui的时候根本不知道stacked Widget的存在,以为界面切换就是不同窗口来回变,所以就出了这种错误。

补救措施

(1)分板块画窗口

我的规划是,登陆注册算一个ui,待办及子界面算一个ui,打卡及子界面算一个ui,规划及子界面算一个ui,笔记及子界面算一个ui。

各个ui的切换依靠hide和show函数,ui内的切换依靠stacked Widget控件

把这里的东西复制下来然后删掉,向里边添加一个Stacked Widget控件,再把这个内容粘贴到第一个窗口,再跟上注册界面的内容。其他ui也效仿这个做

                          

那些残留的ui、cpp、h就没什么用了,看着也很碍眼,直接删了

当然这里的删了是要在项目文件夹里删了,然后还要在pro文件里把和这些文件有关的语句全删了

附工程文件代码,顺手把sql和network库加上,因为这个项目要用到TCP服务器和MySQL

QT       += core gui sql networkgreaterThan(QT_MAJOR_VERSION, 4): QT += widgetsCONFIG += c++17# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0SOURCES += \clock.cpp \main.cpp \mainwindow.cpp \note.cpp \plan.cpp \task.cppHEADERS += \clock.h \mainwindow.h \note.h \plan.h \task.hFORMS += \clock.ui \mainwindow.ui \note.ui \plan.ui \task.uiTRANSLATIONS += \Tick_Task_zh_CN.ts \
CONFIG += lrelease
CONFIG += embed_translations# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

然后下面我就面临了一个可怕的问题:这里很多按钮都是一样的,所以我就把他们的命名设成一样的了。如果不在同一个文件里还好,现在在一个文件里,系统已经自动改了标号,我需要把这些命名再重新改了,要不然后边很难做

改了很长时间,终于勉强改好了,起码给了一个名字我知道它在我的项目里指的是啥

                          

图中为一部分命名,这个东西越改越乱,我的建议是不要想到一个写一个,先想清楚都有什么类型再决定怎么命名

(2)实现界面切换

好了,现在正片开始了,控件已经全部搭好,现在终于可以实现具体功能了。现在先把各个按钮的界面切换功能实现

这是用户进入系统以后看到的第一个界面,我们先把按钮点击注册然后切换到注册界面功能实现

不得不说转到槽真的非常方便

void MainWindow::on_sign_registerButton_clicked()
{ui->stackedWidget->setCurrentIndex(1);
}

在槽函数里写这样一句,就可以实现点击注册键跳到注册界面。

代码解释:调用对象ui的stackedWidget的setCurrentIndex函数,参数是界面的索引,索引从0开始,我的注册放在了第二张,索引就是1

我们依次类推,可以先实现每个ui的内部转换,然后再实现各个大功能的转换

现在用stacked Widget的代码我就不附了,后边ui间的切换我再附一下

好了,经过一段时间,博主已经把每个ui内部的切换弄好了,现在开始弄ui间的切换

分割线---------------------------------------------------------------------------------------------------------------分割线

这是博主最开始的想法,碰壁了

Task *t;

要在构造函数里声明这样一个Task类的指针

//这个函数实现了从登录界面转到待办界面------------------------------------------检测账号密码是否正确还未完成
void MainWindow::on_sign_loginButton_clicked()
{this->hide();t = new Task;t->show();
}

这个代码的意思就是在堆上开一个Task类,然后把主窗口隐藏,再打开新窗口。注释可以很好地提醒我哪些功能还没做,后续可以跟进。注意:要在析构函数里把内存释放掉

接下来就是完成其他主界面的切换,和这个代码是类似的

分割线---------------------------------------------------------------------------------------------------------------分割线

博主还是太年轻了,想当然地以为每个功能类里都声明其他三个类的指针,然后仿照上边这个写法就行了。但是在处理clock类的时候出现了状况,我包含"task,h"的时候编译器报错,说不能递归调用头文件。如果不能在一个类中调用其他三个类的头文件,也就不能声明其他类的对象,就宣告了我的计划破产

现在博主有了更好的方法:利用信号和槽

具体思路:利用mainwindow做中介,其他四个功能类负责发出信号,界面切换按钮按下之后只负责发出信号,其他什么都不用干,然后mainwindow里用connect函数捕获发出的信号,再调用它里边的界面切换函数。这样的话只有mainwindow里需要包含另外四个头文件,功能头文件做好自己就可以了

    Task *t;Clock *c;Plan *p;Note *n;

在MainWindow类的private里声明这四个类的指针

在构造函数里开辟空间

MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow), t(new Task(this)), c(new Clock(this)), p(new Plan(this)), n(new Note(this))
{ui->setupUi(this);
}

在析构函数里释放空间

MainWindow::~MainWindow()
{delete ui;delete t;delete c;delete p;delete n;
}
signals:void taskToPlan();void taskToClock();void taskToNote();

以Task类为例,像这样声明三个信号,然后在槽函数里发出信号

//这个函数的作用是发出一个要切换到打卡界面的信号
void Task::on_task_clockOutButton_clicked()
{emit taskToClock();
}//这个函数的作用是发出一个要切换到规划界面的信号
void Task::on_task_planButton_clicked()
{emit taskToPlan();
}//这个函数的作用是发出一个要切换到笔记界面的信号
void Task::on_task_noteButton_clicked()
{emit taskToNote();
}

这样做好以后在MainWindow里调用切换界面的槽函数就行,不过需要先在MainWindow声明这些函数

    void switchTaskToClock();void switchTaskToPlan();void switchTaskToNote();void switchClockToTask();void switchClockToPlan();void switchClockToNote();void switchPlanToTask();void switchPlanToClock();void switchPlanToNote();void switchNoteToTask();void switchNoteToClock();void switchNoteToPlan();

好了,赏心悦目。然后就是具体实现,我为了举例子就在这里先实现switchTaskToClock函数

在MainWindow里写connect函数

    connect(t, &Task::taskToPlan, this, &MainWindow::switchTaskToPlan);connect(t, &Task::taskToClock, this, &MainWindow::switchTaskToClock);connect(t, &Task::taskToNote, this, &MainWindow::switchTaskToNote);

实现界面切换函数

void MainWindow::switchTaskToClock()
{t->hide();c->show();
}

好了,例子就举到这里。剩下的博主就自己实现了,然后就不附代码了

经过很长一段时间,博主终于弄好了切换,跑出来震惊我了

出现这个的原因是在构造函数时把所有的窗口都show了,需要把它们hide一下

博主在做到这一步的时候又遇到了问题。因为最开始的时候我把登录注册当成了主窗口,其他界面是子窗口,this->hide()就全消失了,所以现在还要把登陆注册独立出来

现在博主要新开一个login.ui及h和cpp,然后按照上边几个界面处理方法来做了。不过由于mainwindow碰的壁太多,所以需要把那里的部分槽函数删了,然后再实现信号传递的槽函数

在这里博主要纠正前边的一个错误

MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow), t(new Task()), c(new Clock()), p(new Plan()), n(new Note()), l(new Login())

这里创建指针的时候不能传入this指针,如果传入this指针的话就相当于是在主窗口内展示,它们实际上没有独立性,为了保持它们的独立性,这里不应该传参,直接默认空指针就行

然后跑出来的话肯定主窗口和后续窗口就是独立的,所以主窗口直接就不用show了,直接show()Login类的窗口

效果展示

博主不知道怎么挂视频,挂不出来,总之是跑出来了,而且很流畅

篇末总结

        这个项目的界面切换博主是走了很多弯路的,虽然在博客中并没有很明显的体现,但是博主线下做这个项目的时候一直是焦头烂额的状态。

        不过万幸的是最后博主也算顺利搞定界面切换了。看到能跑通的项目博主内心是非常高兴的,感觉一切都是值得的

        从无到有实在是很难,我在CSDN、b站、抖音等很多渠道都去搜在Qt中如何实现界面切换,但是没有人告诉我stacked Widget类,也没人告诉我用信号与槽,所以博主在这方面一直栽跟头,有错误也一直找不到

        归根结底还是博主对Qt的理解欠缺,Qt只是一个工具,熟悉它的人自然可以返璞归真。这个进度对博主来说只是冰山一角,后续还要硬肝

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词