[项目:微服务即时通讯系统客户端(基于C++QT)]三,左侧界面搭建

三,左侧界面搭建

一,导入

先把MainWidget类做成“单例类”

采用的是单例模式,让某一个类,在指定进程中只有唯一的实例

先看一下MainWidget的框架

QWidget//这部分是头文件保护宏,确保该头文件只被包含一次,防止因重复包含导致的编译错误。
#ifndef MAINWIDGET_H
#define MAINWIDGET_H//引入 Qt 的 QWidget 类,这个类是所有用户界面对象的基类。
#include <QWidget>//这段代码使用 Qt 的命名空间机制。
//它定义了一个名为 Ui 的命名空间,里面声明了一个名为 mainWidget 的类。
//这个类通常是通过 Qt Designer 生成的,用于管理 UI 元素。
QT_BEGIN_NAMESPACE
namespace Ui {
class mainWidget;
}
QT_END_NAMESPACE//这里定义了一个名为 mainWidget 的类,它继承自 QWidget。Q_OBJECT
class mainWidget : public QWidget
{Q_OBJECTpublic:mainWidget(QWidget *parent = nullptr);~mainWidget();private:Ui::mainWidget *ui;
};
#endif // MAINWIDGET_H
//包含了之前定义的 mainWidget 类的头文件。
#include "mainwidget.h"
//包含了由 Qt Designer 生成的 UI 代码的头文件,通常负责设置 UI 元素。
#include "./ui_mainwidget.h"//这行代码定义了一个静态指针成员变量 instance,初始化为 nullptr。这通常用于实现单例模式,确保 mainWidget 类只有一个实例
mainWidget* mainWidget::instance=nullptr;//构造函数,接受一个可选的父窗口部件指针
mainWidget::mainWidget(QWidget *parent): QWidget(parent)        //调用基类 QWidget 的构造函数,并将父部件传递给它, ui(new Ui::mainWidget) //创建一个新的 Ui::mainWidget 对象,负责设置 UI。
{ui->setupUi(this);       //调用 setupUi 方法,将 UI 组件设置到当前 mainWidget 实例中
}//析构函数
mainWidget::~mainWidget()
{delete ui;
}

二,需求分析

53f9dff501159a97d4c122149e72b38.png

三,代码书写

前置:设置图标,需要把图标图片,导入到项目中,通过qrc文件进行管理

在本章节大致使用了一下素材

素材网站:

https://www.aigei.com/

https://www.iconfont.cn/

userAvatar.jpeglogo.png

apply_active.pngapply_inactive.pngfriend_active.pngfriend_inactive.pngsession_active.pngsession_inactive.png

一,mainWidget.h的编写

#ifndef MAINWIDGET_H
#define MAINWIDGET_H#include <QWidget>
#include <QPushButton>QT_BEGIN_NAMESPACE
namespace Ui {
class mainWidget;
}
QT_END_NAMESPACEclass mainWidget : public QWidget
{Q_OBJECTprivate:static mainWidget* instance;//指针指向当前的类的唯一实例//静态指针,用于指向 mainWidget 类的唯一实例//这是单例模式的核心,确保全局只存在一个 mainWidget 对象//对于单例模式来说,最关键的部分,不是创建实例,而是限制别人创建实例mainWidget(QWidget *parent = nullptr);//他是私有的防止外部代码直接创建mainWidget实例public:static mainWidget*  getInstance();//静态成员函数用于获取当前实例~mainWidget();//析构函数private:Ui::mainWidget *ui;//窗口最左侧部分QWidget* windowLeft;//窗口中间部分QWidget* windowMid;//窗口右侧部分QWidget* windowRight;//用户头像QPushButton* userAvatar;//会话标签页按钮QPushButton* sessionTabBtn;//好友标签页按钮QPushButton* friendTabBtn;//好友申请标签页按钮QPushButton* applyTabBtn;//枚举类型当前的激活的标签页是哪一个enum ActiveTab{SESSION_LIST,FRIEND_LIST,APPLY_LIST};ActiveTab activeTab=SESSION_LIST;//默认为会话列表//初始化主窗口的样式布局void initMainWindow();//初始化左侧窗口布局void initLeftWindow();//初始化中间窗口布局void initMidWindow();//初始化右侧窗口布局void initRightWindow();//信号槽void initSignalSlot();//槽函数void switchTabToSession();void switchTabToFriend();void switchTabToApply();void loadSessionList();void loadFriendList();void loadApplyList();
};
#endif // MAINWIDGET_H

本头文件采用了单例模式

单例模式(Singleton Pattern)是一种设计模式,它确保一个类在程序运行期间只会创建一个实例,并且提供一个全局访问点。

到底此处的代码怎么实现的单例模式呢?

  1. 私有构造函数

  2. 静态实例指针static mainWidget* instance;

  3. 静态访问接口static mainWidget* getInstance();

回顾静态成员的特点
  • 静态成员变量:属于类本身,而不是某个对象。所有类的实例共享同一个静态成员变量,它在程序运行时只会分配一块内存空间。

  • 静态成员函数:同样属于类,而不是对象。它只能访问静态成员变量和静态成员函数,不能访问非静态成员变量和非静态成员函数(因为非静态成员是属于具体对象的)。

单例模式ABC详解

A.构造函数是私有的mainWidget(QWidget *parent = nullptr);

防止外部代码直接创建mainWidget实例

B.**static** 修饰的 **instance** 是一个静态成员变量,它属于 **mainWidget** 类本身,而不是某个特定的 mainWidget 对象.

程序整个周期只存在一份,所有访问mainWidget类的都共享一个instance指针,初始值为nullptr的时候说明还没有创建。

静态成员变量 instance 可以在 mainWidget 类的任何成员函数中访问,也可以通过 getInstance() 方法从类的外部访问。

C.提供对单例实例的访问

mainWidget* mainWidget::getInstance()
{//此处不传入参数,以桌面为父窗口//由于此时的窗口是整个程序的主窗口,父窗口就设定为桌面,本身就是常规设定。if(instance==nullptr){instance=new mainWidget();}return instance;
}

第一次调用 getInstance() 时,创建一个新的实例

第二次以后调用,直接返回instance实例;

二,逐步编写mainwidget.cpp

一,构造函数

mainWidget::mainWidget(QWidget *parent): QWidget(parent), ui(new Ui::mainWidget)
{ui->setupUi(this);//this指向被构造的mainWidgetthis->setWindowTitle("Pokemon聊天室");this->setWindowIcon(QIcon(":/resource/image/logo.png"));//初始化主窗口的样式布局initMainWindow();//初始化左侧窗口布局initLeftWindow();//初始化中间窗口布局initMidWindow();//初始化右侧窗口布局initRightWindow();//初始化信号槽initSignalSlot();
}

二,initMainWindow初始化主窗口

void mainWidget::initMainWindow()
{//创建一个水平布局管理器QHBoxLayout* layout=new QHBoxLayout();//处理间隔Spacing就是layout内部元素之间的间隔距离,设置为0就是紧紧挨着水平的紧紧挨着layout->setSpacing(0);this->setLayout(layout);//将 layout 设置为 mainWidget 窗口的布局管理器//创建三个QWidget子部件windowLeft=new QWidget();windowMid=new QWidget();windowRight=new QWidget();//这三个部分马上添加到布局管理器中//在设计界面的时候,会涉及到很多尺寸,间距,边框,字体相关细节。windowLeft->setFixedWidth(60);//左侧导航栏为固定的70像素windowMid->setFixedWidth(230);//中间windowRight->setMinimumWidth(500);//右边聊天框 根据窗口自动化改变//可以使用qq的截图来进行判定大小//设计颜色qsswindowLeft->setStyleSheet("QWidget {background-color:rgb(23,23,23)}");//左侧导航栏为固定的70像素windowMid->setStyleSheet("QWidget {background-color:rgb(46,46,46)}");windowRight->setStyleSheet("QWidget {background-color:rgb(255,255,255)}");//子窗口添加到布局管理器中layout->addWidget(windowLeft);layout->addWidget(windowMid);layout->addWidget(windowRight);}

image.png

三,initLeftWindow()

//H 代表 Horizontal(水平),V 代表 Vertical(垂直)
void mainWidget::initLeftWindow()
{QVBoxLayout* layout =new QVBoxLayout();layout->setSpacing(20);//设置按钮的间距layout->setContentsMargins(0,70,0,0);//设置左上右下的间距windowLeft->setLayout(layout);//添加用户头像userAvatar =new QPushButton();userAvatar->setFixedSize(45,45);//按钮本身的尺寸userAvatar->setIconSize(QSize(45,45));//按钮自身的尺寸userAvatar->setIcon(QIcon(":/resource/image/userAvatar.jpg"));userAvatar->setStyleSheet("QPushButton{ background-color:transparent;}");layout->addWidget(userAvatar,1,Qt::AlignTop |   Qt::AlignCenter);//1是占据空间的权重,靠上对齐,水平居中layout->addStretch(5);//添加空白处//添加会话标签按钮sessionTabBtn=new QPushButton();sessionTabBtn->setFixedSize(45,45);//按钮本身的尺寸sessionTabBtn->setIconSize(QSize(45,45));//按钮自身的尺寸sessionTabBtn->setIcon(QIcon(":/resource/image/session_active.png"));sessionTabBtn->setStyleSheet("QPushButton{ background-color:transparent;}");layout->addWidget(sessionTabBtn,1,Qt::AlignTop |   Qt::AlignCenter);//添加好友标签页按钮friendTabBtn=new QPushButton();friendTabBtn->setFixedSize(45,45);//按钮本身的尺寸friendTabBtn->setIconSize(QSize(45,45));//按钮自身的尺寸friendTabBtn->setIcon(QIcon(":/resource/image/friend_inactive.png"));friendTabBtn->setStyleSheet("QPushButton{ background-color:transparent;}");layout->addWidget(friendTabBtn,1,Qt::AlignTop |   Qt::AlignCenter);//添加好友申请标签页按钮applyTabBtn=new QPushButton();applyTabBtn->setFixedSize(45,45);//按钮本身的尺寸applyTabBtn->setIconSize(QSize(45,45));//按钮自身的尺寸applyTabBtn->setIcon(QIcon(":/resource/image/apply_inactive.png"));applyTabBtn->setStyleSheet("QPushButton{ background-color:transparent;}");layout->addWidget(applyTabBtn,1,Qt::AlignTop |   Qt::AlignCenter);;layout->addStretch(20);//添加下面的空白处//连接信号槽,处理标签页按钮切换的问题
}

四,initSignalSlot()

void mainWidget::initSignalSlot()
{////连接信号槽,处理标签页按钮切换的问题/connect(sessionTabBtn,&QPushButton::clicked,this,&mainWidget::switchTabToSession);//连接的信号来自sessionTabBtn这个指向 QPushButton 对象的指针//&QPushButton::clicked 表示 QPushButton 类中的 clicked 信号,clicked 信号在 QPushButton 被点击时触发//槽(slot)函数所属对象的指针,指的是 mainWidget 类的一个实例对象,槽函数是在当前对象(即 mainWidget 类的实例)中定义的//最后一个位置是槽函数:每当 sessionTabBtn 发出 clicked 信号时,这个槽函数就会被调用connect(friendTabBtn,&QPushButton::clicked,this,&mainWidget::switchTabToFriend);connect(applyTabBtn,&QPushButton::clicked,this,&mainWidget::switchTabToApply);}

addWidget的参数中1的作用

拉伸系数的作用:它决定了当布局空间发生变化(如窗口大小改变时),该部件在布局中占据的比例。如果拉伸系数为 1,那么它在布局中将获得与其他拉伸系数为 1 的部件相同的空间份额。如果拉伸系数为 0,则该部件的大小不会随布局的空间变化而变化(即固定大小)

五,槽函数

void mainWidget::switchTabToSession()
{//1.记录当前切换到了哪一个标签页activeTab=SESSION_LIST;//2.调整当前图片显示情况,把会话的按钮图标设为active,另两个图标设为inactivesessionTabBtn->setIcon(QIcon(":/resource/image/session_active.png"));friendTabBtn->setIcon(QIcon(":/resource/image/friend_inactive.png"));applyTabBtn->setIcon(QIcon(":/resource/image/apply_inactive.png"));//3.在主窗口中间部分,加载会话列表数据this->loadSessionList();
}
void mainWidget::switchTabToFriend()
{//1.记录当前切换到了哪一个标签页activeTab=FRIEND_LIST;//2.调整当前图片显示情况,把会话的按钮图标设为active,另两个图标设为inactivesessionTabBtn->setIcon(QIcon(":/resource/image/session_inactive.png"));friendTabBtn->setIcon(QIcon(":/resource/image/friend_active.png"));applyTabBtn->setIcon(QIcon(":/resource/image/apply_inactive.png"));//3.在主窗口中间部分,加载会话列表数据this->loadFriendList();
}
void mainWidget::switchTabToApply()
{//1.记录当前切换到了哪一个标签页activeTab=APPLY_LIST;//2.调整当前图片显示情况,把会话的按钮图标设为active,另两个图标设为inactivesessionTabBtn->setIcon(QIcon(":/resource/image/session_inactive.png"));friendTabBtn->setIcon(QIcon(":/resource/image/friend_inactive.png"));applyTabBtn->setIcon(QIcon(":/resource/image/apply_active.png"));//3.在主窗口中间部分,加载会话列表数据this->loadApplyList();
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/429792.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

低级编程语言和高级编程语言

一.区分低级编程语言和高级编程语言的方法 1.低级编程语言 低级编程语言,并不是简单的编程语言,而是写起来很费事的编程语言,如所有编程语言的"祖宗":汇编语言,写起来极其麻烦,说不定一个 int a1; 它就得写好几行,甚至十几行 这样麻烦的编程语言为什么还没消失那,因…

基于微信小程序的家教信息管理系统的设计与实现(论文+源码)_kaic

摘 要 随着互联网时代的来临&#xff0c;使得传统的家教模式已不复存在&#xff0c;亟需一种方便、快捷的在线教学平台。因此&#xff0c;利用Java语言作为支撑和MySQL数据库存储数据&#xff0c;结合微信小程序的便利性&#xff0c;为用户开发出了一个更加人性化、方便的家庭…

超越sora,最新文生视频CogVideoX-5b模型分享

CogVideoX-5B是由智谱 AI 开源的一款先进的文本到视频生成模型&#xff0c;它是 CogVideoX 系列中的更大尺寸版本&#xff0c;旨在提供更高质量的视频生成效果。 CogVideoX-5B 采用了 3D 因果变分自编码器&#xff08;3D causal VAE&#xff09;技术&#xff0c;通过在空间和时…

ps证件照蓝底换白底

ps证件照蓝底换白底 1、打开 Photoshop&#xff0c;导入需要处理的照片。 2、左侧工具栏中选择“魔棒工具”&#xff0c;点击证件照的背景区域进行选择。 3、使用快捷键 Shift F5 或者从顶部菜单选择“编辑” -> “填充”&#xff0c;在弹出的对话框中选择“填充内容”中…

【全网最全】2024年华为杯研究生数学建模A题成品论文

您的点赞收藏是我继续更新的最大动力! 一定要点击如下的卡片&#xff0c;那是获取资料的入口&#xff01; 点击链接获取群聊【2024华为杯研赛资料汇总】&#xff1a;https://qm.qq.com/q/yB6JDUTaWAhttps://qm.qq.com/q/yB6JDUTaWAA题第一问是关于如何建立一个低复杂度模型&a…

【M-LOAM学习】

M-LOAM(INITIALIZATION) Article Analysis Scan-Based Motion Estimation 通过在consecutive frame (each LiDAR)&#xff08;因为omp parallel&#xff09;中寻找correspondences然后通过最小化所有考虑feature之间residual error的transformation between frame to frame 针…

通过解预测和机器学习促进蚁群优化

文章目录 Abstract1. Introduction2. Background and related work2.1 定向越野问题2.2 ACO优化3. 基于预测的蚁群优化算法3.1 构建训练集3.2 训练与解预测3.3 将预测解融入蚁群优化Abstract ML - ACO 算法的第一阶段,使用一组已知最优解的小定向越野问题实例训练一个 ML 模型…

tornado

Tornado通过使用非阻塞网络1/0&#xff0c;可以扩展到数以万计的开放链接&#xff0c;非常适合 长时间轮询&#xff0c;WebSockets和其他需要与每个用户建立长期连接的应用程序。 特点 注重性能优越&#xff0c;速度快解决高并发异步非阻塞websockets 长连接内嵌了HTTP服务器…

Linux 一些快捷键使用操作技巧

ctrl c : 强制停止 如图仅输入tail命令时程序会卡住&#xff0c;这时就需要强制停止 ctrl d : 退出或者登出 history : 查看历史输入命令 &#xff01;命令 &#xff1a;自动执行上一次匹配前缀的命令 &#xff08;注意不要用这个命令执行太过久远的&#xff0c;容易执行错误…

AWS 管理控制台

目录 控制台主页 AWS 账户信息 AWS 区域 AWS 服务选择器 AWS 搜索 AWS CloudShell AWS 控制面板小部件 控制台主页 注册新的 AWS 账户并登录后&#xff0c;您将看到控制台控制面板。这是与各种 AWS 服务以及其他重要控制台组件进行交互的起点。控制面板由页面顶部的导航…

C语言 | Leetcode C语言题解之第423题从英文中重建数字

题目&#xff1a; 题解&#xff1a; char * originalDigits(char * s) {int lenstrlen(s);int arr[26]{0},num[10]{0},cot0;for(int i 0; i < len; i)arr[s[i] - a];num[0] arr[z-a];num[2] arr[w-a];num[4] arr[u-a];num[6] arr[x-a];num[8] arr[g-a];num[1] arr[o…

nginx upstream转发连接错误情况研究

本次测试用到3台服务器&#xff1a; 192.168.10.115&#xff1a;转发服务器A 192.168.10.209&#xff1a;upstream下服务器1 192.168.10.210&#xff1a;upstream下服务器2 1台客户端&#xff1a;192.168.10.112 服务器A中nginx主要配置如下&#xff1a; log_format main…

双向链表:实现、操作与分析【算法 17】

双向链表&#xff1a;实现、操作与分析 引言 双向链表&#xff08;Doubly Linked List&#xff09;是链表数据结构的一种重要形式&#xff0c;它允许节点从两个方向进行遍历。与单向链表相比&#xff0c;双向链表中的每个节点不仅包含指向下一个节点的指针&#xff08;或引用&…

C语言 | Leetcode C语言题解之第429题N叉树的层序遍历

题目&#xff1a; 题解&#xff1a; #define MAX_LEVE_SIZE 1000 #define MAX_NODE_SIZE 10000int** levelOrder(struct Node* root, int* returnSize, int** returnColumnSizes) {int ** ans (int **)malloc(sizeof(int *) * MAX_LEVE_SIZE);*returnColumnSizes (int *)mal…

旋转机械故障数据集 全网首发

旋转机械故障 数据集 11G资料 泵、齿轮箱、电机、流量、液压系统、轴承(西储大学、辛辛那提大学、FEMTO、MOSFET)、PHM08挑战数据集、我闪发动机降级模拟数据集、铣床等 旋转机械故障数据集 数据集描述 该数据集是一个综合性的旋转机械故障检测和诊断数据集&#xff0c;旨在…

【QT】系统-下

欢迎来到Cefler的博客&#x1f601; &#x1f54c;博客主页&#xff1a;折纸花满衣 &#x1f3e0;个人专栏&#xff1a;QT 目录 &#x1f449;&#x1f3fb;QTheadrun() &#x1f449;&#x1f3fb;QMutex&#x1f449;&#x1f3fb;QWaitCondition&#x1f449;&#x1f3fb;Q…

C/C++内存管理 ——

目录 五、C/C内存管理 1、C/C内存分布 2、C语言中动态内存管理方式&#xff1a;malloc/calloc/realloc/free 3、C内存管理方式 1.new/delete操作内置类型 2.new和delete操作自定义类型 4、operator new与operator delete函数 5、new和delete的实现原理 1.内置类…

分布式事务详细笔记:什么是分布式事务--Seata--XA模式--AT模式

目录 1.分布式事务 1.1.什么是分布式事务 1.2.认识Seata 1.3.部署TC服务 1.3.1.准备数据库表 1.3.2.准备配置文件 1.3.3.Docker部署 1.4.微服务集成Seata 1.4.1.引入依赖 1.4.2.改造配置 1.4.3.添加数据库表 1.5.XA模式 1.5.1.两阶段提交 1.5.2.Seata的XA模型 1…

网络原理 HTTP与HTTPS协议

博主主页: 码农派大星. 数据结构专栏:Java数据结构 数据库专栏:MySQL数据库 JavaEE专栏:JavaEE 关注博主带你了解更多计算机网络知识 目录 1.HTTP概念 2.HTTP报文格式 3.HTTP请求 1.首行 1.1URL 1.2 GET⽅法 1.3 POST⽅法 1.4 其他⽅法 2.请求头&#xff08;head…

专业学习|动态规划(概念、模型特征、解题步骤及例题)

一、引言 &#xff08;一&#xff09;从斐波那契数列引入自底向上算法 &#xff08;1&#xff09;知识讲解 &#xff08;2&#xff09;matlap实现递归 &#xff08;3&#xff09;带有备忘录的遗传算法 &#xff08;4&#xff09;matlap实现带有备忘录的递归算法 “&#xff1…