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()槽,传递给它AcceptedRejected

下面正式看代码:

//注册账号
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局域网聊天软件”项目-常用编程技巧总结的更多相关文章

  1. 仿QQ局域网聊天软件

    1 目的   想复习一下TCP/IP协议,再结合一下以前学的Qt的知识,加上前段时间学的MySQL数据库操作,所以写了个"仿QQ局域网聊天软件"小项目,只实现了一部分功能,还没写完 ...

  2. 高仿QQ即时聊天软件开发系列之三登录窗口用户选择下拉框

    上一篇高仿QQ即时聊天软件开发系列之二登录窗口界面写了一个大概的布局和原理 这一篇详细说下拉框的实现原理 先上最终效果图 一开始其实只是想给下拉框加一个placeholder效果,让下拉框在未选择未输 ...

  3. 高仿QQ即时聊天软件开发系列之二登录窗口界面

    继上一篇高仿QQ即时聊天软件开发系列之一开端之后,开始做登录窗口 废话不多说,先看效果,只有界面 可能还有一些细节地方没有做,例如那个LOGO嘛,不要在意这些细节 GIF虽短,可是这做起来真难,好吧因 ...

  4. 高仿QQ即时聊天软件开发系列之一开端

    前段时间在园子里看到一个大神做了一个GG2014IM软件,仿QQ的,那感觉···,赶快下载源码过来试试,还真能直接跑起来,效果也不错.但一看源码,全都给封装到了ESFramework里面了,音视频那部 ...

  5. SignalR快速入门 ~ 仿QQ即时聊天,消息推送,单聊,群聊,多群公聊(基础=》提升)

     SignalR快速入门 ~ 仿QQ即时聊天,消息推送,单聊,群聊,多群公聊(基础=>提升,5个Demo贯彻全篇,感兴趣的玩才是真的学) 官方demo:http://www.asp.net/si ...

  6. 局域网聊天软件(winsocket)

    LANChat工作整理 2013/8/22 程序实现功能: 局域网聊天软件,启动即可找到在线设备,并能够进行简单的文字聊天. 其实下面这个框图已经说明了程序的绝大部分功能原理. 核心类的程序框图 我觉 ...

  7. 聊天软件项目TCP升级版

    //聊天软件项目TCP升级版 import java.io.*; import java.net.*; class TcpClient2 { public static void main(Strin ...

  8. c#局域网聊天软件的实现

    本软件是基于大学寝室局域网聊天的思路.c#源代码如下: using System; using System.Drawing; using System.Collections; using Syst ...

  9. java 网络编程基础 UDP协议DatagramSocket,MulticastSocket 实现局域网聊天软件(Server + Client模式)

      开发思路: 服务端两个Socket: UDP的DatagramSocket接收客户端消息. 广播multicastSocket 发送广播消息 客户端一个Socket: multicastSocke ...

随机推荐

  1. Linux操作系统下IPTables配置

    filter表的防火墙 1.查看本机关于IPTABLES的设置情况 [root@tp ~]# iptables -L -n Chain INPUT (policy ACCEPT) target pro ...

  2. hdu_1398_Square Coins_201404260953

    Square Coins Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Tota ...

  3. TCP/IP学习笔记(4)------ICMP,ping,traceroute

    IMCP协议介绍 当传送IP数据包发生错误--比如主机不可达,路由不可达等等,ICMP协议将会把错误信息封包,然后传送回给主机.给主机一个处理错误的机会,这 也就是为什么说建立在IP层以上的协议是可能 ...

  4. 【Spark】Spark容错机制

    引入 一般来说,分布式数据集的容错性有两种方式:数据检查点和记录数据的更新. 面向大规模数据分析,数据检查点操作成本非常高,须要通过数据中心的网络连接在机器之间复制庞大的数据集,而网络带宽往往比内存带 ...

  5. Spring_2_Spring中lazy-init和scope属性

    1)springTest类: public class springTest { @Test public void instanceSpring() { AbstractApplicationCon ...

  6. 我怎么在AD里面找到已经改名的Administrator账户?

    近期有博友问我一个问题,他是一个企业里面的IT管理员,他非常苦恼.他是一个新手,之前管理员交接的时候,没有交接更改的管理员username和password.他如今不知道哪个才是系统之前内置的admi ...

  7. NYOJ 298-点的变换(经典矩阵解决点平移、缩放、翻转和旋转)

    题目地址:NYOJ 298 思路:该题假设用对每一个点模拟的操作.时间复杂度为O(n+m),结果肯定超时.然而利用矩阵乘法能够在O(m)的时间内把全部的操作合并为一个矩阵,然后每一个点与该矩阵相乘能够 ...

  8. ubuntu上跑python连接pg,报错 ImportError: No module named psycopg2

    ubuntu上跑python连接pg,报错  ImportError: No module named psycopg2 root@pgproxy1:~# python /home/zxw/PGWri ...

  9. Cocos2d-X中的ProgressTimer

     ProgressTimer即进度条,进度条在游戏开发中运用很广泛,比如在一些格斗游戏中,显示血液的变化,还有游戏载入进度,等都离不开进度条 Cocos2d-X中使用CCProgressTimer ...

  10. 转:js点击事件在ios中失效的3种解决方案

    ios中不允许将点击事件绑定在document或者body上,如果绑定上的话将会失效.解决方案: 例如:  $(document).on('click', '#generate', function ...