zoukankan      html  css  js  c++  java
  • “仿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()槽,传递给它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(),才能真正插入数据
    
  • 相关阅读:
    A3纸双面打印对折页设置方法
    BAD SYSTEM CONFIG INFO蓝屏解决办法
    局域网内Win7系统怎么开启远程桌面
    word批量删除换行符
    excel复制到word,表格格式错乱解决办法
    word取消回车自动编号
    被深信服上网行为管理器AC拒绝的操作如何正常访问
    震旦AD248复印机如何复印身份证正反面
    Win10开机后黑屏需强制关机再开机才能进桌面怎么办
    Windows已经发现此文件有一个问题
  • 原文地址:https://www.cnblogs.com/linuxAndMcu/p/10191959.html
Copyright © 2011-2022 走看看