基于qt的局域网聊天系统设计论文内容摘要:

, QT 的 signals 关键字指出进入了信号声明区,随后即可 声明自己的信号。 例如,下面定义了三个信号: void mySignal()。 void mySignal(int x)。 void mySignalParam(int x,int y)。 槽是普通的 C++ 成员函数,可以被正常调用,它们唯一的特殊性就是很多信号可以与其相关联。 当与其关联的信号被发射时,这个槽就会被调用。 槽可以有参数,但槽的参数不能有缺省值。 既然槽是普通的成员函数,因此与其它的函数一样,它们也有存取权限。 槽的存取权限决定了谁能够与其相关联。 同普通的 C++ 成员函数一样,槽函数也分为三种类型,即 public slots、 private slots 和 protected slots。 public slots:在这个区内声明的槽意味着任何对象都可将信号与之相连接。 这 对于组件编程非常有用,你可以创建彼此互不了解的对象,将它们的信号与槽进行连接以便信息能够正确的传递。 protected slots:在这个区内声明的槽意味着当前类及其子类可以将信号与之相连接。 这适用于那些槽,它们是类实现的一部分,但是其界面接口却面向外部。 private slots:在这个区内声明的槽意味着只有类自己可以将信号与之相连接。 这适用于联系非常紧密的类。 信号与槽的关联 : 11 通过调用 QObject 对象的 connect 函数来将某个对象的信号与另外一个对象的槽函数相关联,这样当发射者发射 信号时,接收者的槽函数将被调用。 该函数的定义如下: bool QObject::connect ( const QObject * sender, const char * signal, const QObject * receiver, const char * member ) [static] 这个函数的作用就是将发射者 sender 对象中的信号 signal 与接收者 receiver 中的 member 槽函数联系起来。 当指定信号 signal 时必须使用 QT 的宏 SIGNAL(),当指定槽函数时必须使用宏 SLOT()。 如果发射者与接收者属于同一个对象的话,那么在 connect 调用中接收者参数可以省略。 当信号与槽没有必要继续保持关联时,我们可以使用 disconnect 函数来断开发射者中的信号与接收者中的槽函数之间的关联。 其定义如下: bool QObject::disconnect ( const QObject * sender, const char * signal, const Object * receiver, const char * member ) [static] 元对象工具 : 元对象编译器 moc( meta object piler) 对 C++ 文件中的类声明进行分析并产生用于初始化元对象的 C++ 代码,元对象包含全部信号和槽的名字以及指向这些函数的指针。 moc 读 C++ 源文件,如果发现有 Q_OBJECT 宏声明的类,它就会生成另外一个 C++ 源文件,这个新生成的文件中包含有该类的元对象代码。 例如,假设我们有一个头文件 ,在这个文件中包含有信号或槽的声明,那么在编译之前 moc 工具就会根据该文件自动生成一个 名为 的 C++ 源文件并将其提交给编译器;类似地,对应于 文件 moc 工具将自动生成一个名为 文件提交给编译器。 元对象代码是 signal/slot 机制所必须的。 用 moc 产生的 C++ 源文件必须与类实现一起进行编译和连接,或者用 include 语句将其包含到类的源文件中。 moc 并不扩展 include 或者 define 宏定义 , 它只是简单的跳过所遇到的任何预处理指令。 信号与槽机制是比较灵 活的,但有些局限性我们必须了解,这样在实际的使用过程中做到有的放矢,避免产生一些错误。 下面就介绍一下这方面的情况。 12 1 .信号与槽的效率是非常高的,但是同真正的回调函数比较起来,由于增加了灵活性,因此在速度上还是有所损失,当然这种损失相对来说是比较小的,通过在一台 i586133 的机器上测试是 10 微秒(运行 Linux),可见这种机制所提供的简洁性、灵活性还是值得的。 但如果我们要追求高效率的话,比如在实时系统中就要尽可能的少用这种机制。 2 .信号与槽机制与普通函数的调用一样,如果使用不当的话,在程 序执行时也有可能产生死循环。 因此,在定义槽函数时一定要注意避免间接形成无限循环,即在槽中再次发射所接收到的同样信号。 例如 , 在前面给出的例子中如果在 mySlot() 槽函数中加上语句 emit mySignal() 即可形成死循环。 3 .如果一个信号与多个槽相联系的话,那么,当这个信号被发射时,与之相关的槽被激活的顺序将是随机的。 4. 宏定义不能用在 signal 和 slot 的参数中。 5. 构造函数不能用在 signals 或者 slots 声明区域内。 6. 函数指针不能作为信号或槽的参数。 7. 信号与槽不能有缺省参数。 8. 信号与槽也不能携带模板类参数。 9. 嵌套的类不能位于信号或槽区域内,也不能有信号或者槽。 10. 友元声明不能位于信号或者槽声明区内。 13 4 系统设计 系统总体构架 本系统采用 c/s 构架并以 Qt 技术为基础,实现局域网的聊天系统。 系统要求能够实现聊天功能,能够传输文件,并能够更改字体大小和颜色及文字加粗倾斜和下划线功能。 系统主体框架包括获取用户信息,系统界面设计,消息发送及文件传输。 系统要求完成的设计如下图 2: 图 2 系统的主要 功能模块 Socket 运用 文字聊天及文件传输是本设计功能实现的核心。 Qt 提供了 QTcpSocket 类,QTcpServer 类和 QUdpSocket 类等供开发人员使用。 QTcpSocket 类提供一个 TCP 套接字,帮助开发人员创建 TCP 连接和数据交流。 QTcpServer 类用来与客户端连线,以实现数据的传输。 TCP 服务器及客户端的数据交流流程如下图 3: 14 图 3数据交流流程图 界面设计 Qt拥有强大的 UI编辑器,开发者可以很方便的构架出系统的的图形界面,再利用IDE编程实 现底层的信号和槽函数的设计,具体的窗口部件如下图 4所示: 图 4主界面的部件 其中文字状态又分为六个部分,即字体大小,字体选择,字体加粗,字体倾斜,下划线和字体颜色。 用户信息栏包括用户名,主机名和用户 ID。 消息状态栏包括清除聊天记录和保存聊天记录两个部分。 当传输文件时服务器端和客户端都需要开启新的窗口。 服务器端开启窗口显示所要选择发送的文件路径,发送进度,发送及退出按钮。 窗口如下图 5所示: 15 图 5服务器端发送文件 客户端作为文件的接受端,其窗口与服务器端相差无几,主要由取消,关闭按钮及等待 进度构成,具体窗口如下图 6所示: 图 6客户端接收文件 16 5 设计实现 获取用户信息 QStringList 类提供了一个字符串列表从 QList QString继承而来,它提供快速索引为基础的接入以及快速插入和清除。 其成员函数用于操作这个字符串列表如append(), insert(), replace(), removeAll(), removeAt(), removeFirst(), removeLast(), and removeOne()等 1. 增加字符串 QStringList fonts。 fonts Arial Helvetica Times Courier。 2. 合并字符串使用 join( ) QString str = (,)。 3. 拆分字符串 QString str = Arial, Helvetica, Times, Courier。 QStringList list1 = (,)。 4. 索引 IndexOf() 函数返回给定字符 串的第一个出现的索引。 而 lastIndexOf() 函数,返回字符串的最后一次出现的索引。 5. 替换 replaceInStrings() QStringList files。 files $QTDIR/src/moc/ ($QTDIR, /usr/lib/qt)。 6. 过滤 filter() 可以让你提取一个新的列表只包含这些字符串包含一个特定的字符串(或匹配特定正则表达式): QStringList list。 list Bill Murray John Doe Bill Clinton。 QStringList result。 result = (Bill)。 // result: [Bill Murray, Bill Clinton 17 foreach 语句为数组或对象集合中的每个元素重复一个嵌入语句组。 foreach 语句用于循环访问集合以获取所需信息,但不应用于更改集合内容以避免产生不可预知的副作用。 Qprocess::systemenvironment() 返回当前进程的环境列表,即一个详细的路径,因此可以获得用户名。 QTableWidgetItem 用来表示表格中的一个单元格,正个表格都需要用逐个单元格构建起来。 //处理新用户加入 void Widget::newParticipant(QString userName,QString localHostName,QString ipAddress) { bool bb=uitableWidgetfindItems(localHostName, Qt::MatchExactly).isEmpty()。 if(bb) { QTableWidgetItem *user = new QTableWidgetItem(userName)。 QTableWidgetItem *host = new QTableWidgetItem(localHostName)。 QTableWidgetItem *ip = new QTableWidgetItem(ipAddress)。 uitableWidgetinsertRow(0)。 uitableWidgetsetItem(0,0,user)。 uitableWidgetsetItem(0,1,host)。 uitableWidgetsetItem(0,2,ip)。 uitextBrowsersetTextColor(Qt::gray)。 uitextBrowsersetCurrentFont(QFont(Times New Roman,10))。 uitextBrowserappend(tr(%1 在线。 ).arg(userName))。 uionlineUsersetText(tr(在线人数: %1).arg(uitableWidgetrowCount()))。 sendMessage(NewParticipant)。 } } 18 //获取用户名 QString Widget::getUserName() { QStringList envVariables。 envVariables USERNAME.* USER.* USERDOMAIN.* HOSTNAME.* DOMAINNAME.*。 QStringList environment = QProcess::systemEnvironment()。 foreach (QString string, envVariables) { int index = (QRegExp(string))。 if (index != 1) { QStringList stringList = (index).split(39。 =39。 )。 if (() == 2) { return (1)。 break。 } } } return false。 } //获取 ip地址: QStrin。
阅读剩余 0%
本站所有文章资讯、展示的图片素材等内容均为注册用户上传(部分报媒/平媒内容转载自网络合作媒体),仅供学习参考。 用户通过本站上传、发布的任何内容的知识产权归属用户或原始著作权人所有。如有侵犯您的版权,请联系我们反馈本站将在三个工作日内改正。