“仿QQ局域网聊天软件”项目-常用编程技巧总结
1 信号槽篇
qqLogin loginDialog;
QQ mainDialog;
loginDialog.show();
//连接登陆窗口和主窗口
QObject::connect(&loginDialog,SIGNAL(SignalShowMainDialog(QTcpSocket *,QStringList)),&mainDialog,SLOT(SlotAcceptLogin(QTcpSocket *,QStringList)));
QStringList strlistUser;
strlistUser.append(userInfoArr[0]); //自身昵称
strlistUser.append(userInfoArr[1]); //自身QQ账号
strlistUser.append(userInfoArr[2]); //头像文件路径
strlistUser.append(userInfoArr[3]); //个性签名
emit SignalShowMainDialog(m_TcpSocket,strlistUser);//发射显示主窗口的信号,并把socket和QQ账号发给主窗口
上述两段代码实现了在“登陆窗口”按下“登陆按钮”后,打开“主窗口”,并把与服务器连接的m_TcpSocket
和用户信息传递给“主窗口”,展示了信号槽机制在不同窗口间传递数据的过程。如果要传递多个不同类型的数据,可以自定义一个结构体,通过结构体指针传递。
2 界面跳转篇
讲解之前,我们先讲述一下非模式对话框和模式对话框的含义。
一. 非模式对话框
非模式对话框是和同一个程序中其它窗口操作无关的对话框。在字处理软件中查找和替换对话框通常是非模式的来允许同时与应用程序主窗口和对话框进行交互。调用show()
来显示非模式对话框。show()
立即返回,这样调用代码中的控制流将会继续。在实践中你将会经常调用show()并且在调用show()的函数最后,控制返回主事件循环。
二. 模式对话框
模式对话框就是阻塞同一应用程序中其它可视窗口的输入的对话框:用户必须完成这个对话框中的交互操作并且关闭了它之后才能访问应用程序中的其它任何窗口。模式对话框有它们自己的本地事件循环。用来让用户选择一个文件或者用来设置应用程序参数的对话框通常是模式的。调用exec()
来显示模式对话框。当用户关闭这个对话框,exec()
将提供一个可用的返回值并且这时流程控制继续从调用exec()
的地方进行。通常,我们连接默认按钮,例如“OK”到accept()槽并且把“Cancel”连接到reject()槽,来使对话框关闭并且返回适当的值。另外我们也可以连接done()槽,传递给它Accepted或Rejected。
下面正式看代码:
//注册账号
void qqLogin::on_registerPushButton_clicked()
{
Cregister registerDialog;//注册窗口的实例化对象
registerDialog.setTcpSocker(m_TcpSocket);
QObject::connect(&loginDialog,SIGNAL(SignalShowMainDialog(QTcpSocket *,QStringList)),&mainDialog,SLOT(SlotAcceptLogin(QTcpSocket *,QStringList)));
this->hide();//当前登陆窗口隐藏
if(registerDialog.exec() == Cregister::Accepted)
this->show();//再显示登陆窗口
}
//“注册窗口”的取消按钮处理
void Cregister::on_cancelPushButton_clicked()
{
this->accept();//执行该语句,该Cregister实例窗口会关闭
}
registerDialog.exec()
的意思是:执行模式对话框,显示"注册窗口",并在这里阻塞住,知道该窗口被关闭之后,才继续往下运行。正因为在这里阻塞住了,所以才没有执行this->show()
,再显示登陆窗口。
调用this->accept();
的作用是:将当前的窗口隐藏(这样就做到窗口功能消失这个功能),并且发送accepted
信号,也就是设置设置结果代码为Accepted。
后面就好理解了,当“注册窗口”的取消按钮按下后,调用this->accept();
,发出accepted
的信号,“注册窗口”关闭,if(registerDialog.exec() == Cregister::Accepted)
这句话成立,所以继续执行到this->showshow()
这句话,然后显示“登陆窗口”。
3 正则表达式篇
//设置正则表达式
QValidator *accountValidator = new QRegExpValidator(QRegExp("[0-9]{10}")); //设置"账号输入栏",只能输入数字0-9,不超过10位
ui->userNameLineEdit->setValidator(accountValidator);
QValidator *passwordValidator = new QRegExpValidator(QRegExp("[0-9]{10}"));
ui->passwdLineEdit->setValidator(passwordValidator);
上面代码通过正则表达式,可以设置文本输入栏的输入限制,比如设置输入必须要是数字,以及设置输入位数。
4 MySQL数据库命令篇
在Qt中连接MySQL数据库:
QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
db.setHostName("localhost");
db.setDatabaseName("mydata");
db.setUserName("root");
db.setPassword("root");
if (!db.open())
{
QMessageBox::critical(nullptr, QObject::tr("无法打开数据库"),
"无法创建数据库连接!", QMessageBox::Cancel);
return false;
}
创建数据库表:
QSqlQuery query;
//创建用户信息表(userTable): 昵称、QQ账号、在线状态(bit)
query.exec("create table userTable(id varchar(20) primary key, nickname varchar(40), account varchar(20), pwd varchar(20), onlineStatus bit)character set = utf8");
插入数据到表中:
QSqlQuery query;
//插入初始"用户信息"到表"userTable"中
query.exec("insert into userTable values('1', '凛冬将至', '359194773', '6981', 0)");
查找表比较账号和密码,看数据库是否有该用户:
bool findUserFlag = false;
//从表"userTable"中查找用户信息
QSqlQuery query;
query.exec("select nickname,account,pwd from userTable");
while(query.next())
{
if(query.value(1).toString() == userAccount && query.value(2).toString() == userPasswd)
{
//数据库表:昵称、账号、密码
m_userInfoArr[0] = query.value(0).toString();
m_userInfoArr[1] = query.value(1).toString();
m_userInfoArr[2] = query.value(2).toString();
findUserFlag = true;
break;
}
}
设置表的单个数据:
//将该用户的在线状态设置为1
if(findUserFlag)
{
query.prepare(QString("update userTable set onlineStatus = ? where account = %1 ").arg(userAccount));
query.bindValue(0,1); //0表示第一个属性onlineStatus,将其值设置为1
query.exec();
}
设置表的多个数据:
//将从客户端"注册窗口"接收到的"用户信息",插入到表"userTable"中
if (query.prepare("INSERT INTO userTable(id,nickname,account,pwd,onlineStatus)" \
"VALUES(:id,:nickname,:account,:pwd,:onlineStatus)"))
qDebug() <<"数据库准备成功";
query.bindValue(":id",iDataSize);
query.bindValue(":nickname",strNickname);
query.bindValue(":account",strQQAccount);
query.bindValue(":pwd",strPwd);
query.bindValue(":onlineStatus",0);
query.exec(); //执行完query.exec(),才能真正插入数据
“仿QQ局域网聊天软件”项目-常用编程技巧总结的更多相关文章
- 仿QQ局域网聊天软件
1 目的 想复习一下TCP/IP协议,再结合一下以前学的Qt的知识,加上前段时间学的MySQL数据库操作,所以写了个"仿QQ局域网聊天软件"小项目,只实现了一部分功能,还没写完 ...
- 高仿QQ即时聊天软件开发系列之三登录窗口用户选择下拉框
上一篇高仿QQ即时聊天软件开发系列之二登录窗口界面写了一个大概的布局和原理 这一篇详细说下拉框的实现原理 先上最终效果图 一开始其实只是想给下拉框加一个placeholder效果,让下拉框在未选择未输 ...
- 高仿QQ即时聊天软件开发系列之二登录窗口界面
继上一篇高仿QQ即时聊天软件开发系列之一开端之后,开始做登录窗口 废话不多说,先看效果,只有界面 可能还有一些细节地方没有做,例如那个LOGO嘛,不要在意这些细节 GIF虽短,可是这做起来真难,好吧因 ...
- 高仿QQ即时聊天软件开发系列之一开端
前段时间在园子里看到一个大神做了一个GG2014IM软件,仿QQ的,那感觉···,赶快下载源码过来试试,还真能直接跑起来,效果也不错.但一看源码,全都给封装到了ESFramework里面了,音视频那部 ...
- SignalR快速入门 ~ 仿QQ即时聊天,消息推送,单聊,群聊,多群公聊(基础=》提升)
SignalR快速入门 ~ 仿QQ即时聊天,消息推送,单聊,群聊,多群公聊(基础=>提升,5个Demo贯彻全篇,感兴趣的玩才是真的学) 官方demo:http://www.asp.net/si ...
- 局域网聊天软件(winsocket)
LANChat工作整理 2013/8/22 程序实现功能: 局域网聊天软件,启动即可找到在线设备,并能够进行简单的文字聊天. 其实下面这个框图已经说明了程序的绝大部分功能原理. 核心类的程序框图 我觉 ...
- 聊天软件项目TCP升级版
//聊天软件项目TCP升级版 import java.io.*; import java.net.*; class TcpClient2 { public static void main(Strin ...
- c#局域网聊天软件的实现
本软件是基于大学寝室局域网聊天的思路.c#源代码如下: using System; using System.Drawing; using System.Collections; using Syst ...
- java 网络编程基础 UDP协议DatagramSocket,MulticastSocket 实现局域网聊天软件(Server + Client模式)
开发思路: 服务端两个Socket: UDP的DatagramSocket接收客户端消息. 广播multicastSocket 发送广播消息 客户端一个Socket: multicastSocke ...
随机推荐
- [K/3Cloud] 单据新增、复制、新增行、复制行的过程
整单复制:先执行CopyData(获得数据包),在执行AfterCreateNewData(可处理数据包),不会执行AfterCreateNewEntryRow 单据新增:先执行AfterCreate ...
- CentOS7下安装单机版RabbitMQ及权限赋予
RabbitMQ官网rpm软件包地址:https://www.rabbitmq.com/releases/ 一.安装环境: CentOS7.erlang-19.0.4-1.el7.centos.x86 ...
- [bzoj2962]序列操作_线段树_区间卷积
序列操作 bzoj-2962 题目大意:给定一个n个数的正整数序列,m次操作.支持:1.区间加:2.区间取相反数:3.区间求选c个数的乘积和. 注释:$1\le n,m\le 5\cdot 10^4$ ...
- POJ——T 2728 Desert King
http://poj.org/problem?id=2728 Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 27191 ...
- JavaScript为字符串添加样式
<script type="text/javascript"> var txt="Hello World!" document.write(&quo ...
- Ionic3 填坑记录 - java.lang.RuntimeException: java.lang.RuntimeException: com.android.builder.dexing.DexArchiveMergerException: Unable to merge dex
1 错误:Unable to merge dex 执行打包命令时 ionic cordova build android --prod 报如下错误 2 原因 重复引用了同一个包 如上图所示, com ...
- Map根据value排序ASC DESC
原文:http://blog.csdn.net/k21325/article/details/53259180 需求有点刁钻,写关键词组合匹配标题的时候,遇到关键词像这样 XXX XXX 1222 X ...
- jQuery异步框架探究1:jQuery._Deferred方法
jQuery异步框架应用于jQuery数据缓存模块.jQuery ajax模块.jQuery事件绑定模块等多个模块,是jQuery的基础功能之中的一个.实际上jQuery实现的异步回调机制能够看做ja ...
- iOS社交分享Twitter、Facebook、拷贝到剪切板、LINE、及邮件
准备 首先要引进例如以下三个framework: MessageUI.framework Social.framework Accounts.framework 并在实现这几个方法的地方引入下面几个头 ...
- Android之——多线程下载演示样例
转载请注明出处:http://blog.csdn.net/l1028386804/article/details/46883927 一.概述 说到Android中的文件下载.Android API中明 ...