“仿QQ局域网聊天软件”项目-常用编程技巧总结

摘要:
I非模态对话框非模态对话框是与同一程序中的其他窗口操作无关的对话框。在文字处理软件中,查找和替换对话框通常是非模态的,以允许与应用程序的主窗口和对话框同时交互。调用show()以显示无模式对话框。II模式对话框是阻止同一应用程序中其他可视窗口输入的对话框:用户必须完成此对话框中的交互并在访问应用程序中的任何其他窗口之前将其关闭。模态对话框有自己的本地事件循环。

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局域网聊天软件”项目-常用编程技巧总结》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇GraphQL Java数据阵列Raid5磁盘阵列知识下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

java实现发送QQ邮箱

一、前期准备 准备两个qq邮箱号,本例使用的是自己的两个邮箱 syc582535560@foxmail.com 2212444549@qq.com 下载javax.mail.jar jar包 如使用maven,在pom.xml里添加 <dependency><groupId>javax.mail</groupId><...

批处理文件——多个QQ一键登录

       偶然看到有的同学登录PC的QQ,发现他有很多QQ,每登录一个要切换一个,虽然记住了密码,但还是不方便,于是想通过批处理来实现“一键登录”的功能。以下内容为本文假想,如有雷同,实属巧合!        具体的实现步骤如下:        (1)首先,查看QQ安装时的文档位置(用于保存用户登录历史记录),我的是:C:UsersDavidDocum...

【原创+亲测可用】JS如何区分微信浏览器、QQ浏览器和QQ内置浏览器

1、原理: 通过不同移动端的ua弹窗 获取user-agent 参数包含的信息,进行判断浏览器类型 在Android上 QQ内置环境的ua中有关键字 MQQBrowser, 并且后面包含一个【空白符+QQ】字符;QQ浏览器仅有【MQQBrowser】因此在Android上区分,需要用正则判断ua中包含MQQBrowser,并且剔除【MQQBrowser...

C#编写QQ接口软件——QQ协议篇

转自 http://www.iqidi.com/Articles/2009-04-19%23329.htm 1、找寻支持QQ HTTP协议的服务器 大家也许会被一些假像所迷惑,也许会认为QQ的HTTP服务器是基于80口进行通信的(如: 218.17.209.23:80),其实不然,正真基于HTTP的服务器应该是:http://tqq.tencent.co...

js,jq,php使用正则方法

1.js使用正则表达式案例: <script> var str=”543535364565@qq.com”; var res=“/^d*@(QQ|qq|136).(com|cn)$/”; var result=res.exec(str); alert(result); </script> 2.php使用正则表达式案例: $em...

Java编程技巧:if-else优化实践总结归纳

文/朱季谦 说实话,其实我很讨厌在代码里大量使用if-else,一是因为该类代码执行方式属于面向过程的,二嘛,则是会显得代码过于冗余。这篇笔记,主要记录一些自己在工作实践当中针对if-else的优化心得,将会不定期地长期更新。 一、使用策略枚举来优化if-else 看到网上蛮多人推荐使用策略模式来优化if-else,但我总觉得,搞一堆策略类来优化大批量if...