总结一下开发中遇到的问题:
1.一个方法:关于在建立程序之初,用一个类的静态对象来控制整个程序。
本来我想的是,建立一个名字叫MyApplication的类来继承QApplication()类,并以此作为整个程序的主进程来操作,但是这样操作很麻烦,当然,这样显然是可以的。但有个问题,就是继承QApplication类需要传入两个参数,这两个参数我们并不知道有什么用,而且我们声明全局变量的时候,能不能直接就向其中传入(0,null)这样的参数呢?这个MyApplication会不会因此为空呢?这些我在实际操作中试验过,但结果是什么我已经忘得差不多了,之后可能会单独写demo实验一下。
还有种另外的方法就是:写一个类,然后用一个声明/获取 静态对象一体的方法,来做一个全局的控制。怎么实现呢?举个例子:
我们可以声明一个普通的类tApp,
注意你这是在qt内来用的,所以这个类应该继承QObject
class tApp : public QObject
{
Q_OBJECT
public:
tApp();
~tApp();
然后我们可以声明一个方法
static tApp& tApp::theApp();
这个方法的定义如下
tApp & tApp::theApp()
{
static tApp theApp;
return theApp;
// TODO: 在此处插入 return 语句
}
如果当前没有这么个theApp的静态对象时,则初始化声明这么个theApp类,如果当前这个theApp静态对象已经被声明了,那么可以通过theApp()方法调用这个静态对象,如果我们想要connect 这个指针呢?那就可以直接在前面加个&符号来取这个地址。
然后呢?我们可以把所有的窗体控制、网络控制、关键数据、输入、输出塞到这个tApp类中,而不是塞到某个特定的窗体中进行,然后通过connect,将窗体、网络、数据之间的信号连接,这样就可以避免了一些兄弟窗体之间通信的问题。
2.QJson字符串,因为开始不知道这个是什么东西,所以这个也折磨了我很久。
关于QJson相关的内容,详情可以见这个连接QJson的生成和解析,这个实例写的蛮好的,之后我也会陆续上传一些demo实例来作为例子,这里举例如下:QJsonDemo
3.界面之间,如果是自己的软件内的,可以直接传一整个结构,不用一个值一个值单独传
这是我踩过最严重的坑,没有之一。
讲下开发的时候发生了什么:在做这个程序的时候,我还没有先做进程类,或者静态类来处理整个界面的想法,而是直接进来就直接到页面了,然后所有的控制处理,和信号传递,都通过这个页面来进行。但开发到后面才发现,原来这个页面前面还有另外的一个页面,但由于前面这个页面的存在,整个软件的操作和信号传递都变得极其不方便。
这还不是最主要的,最主要的是–在我不知道json字符串的时候,两个界面之间传递数据还是通过正则进行,这就很坑爹了。
如果是通过json,那么两个窗体之间又需要单独地进行一些打包和解析,这不进为后续的开发造成了隐患,还会让整个程序变得无法维护。
所以界面之间,如果可以的话,直接传递数据结构是最好的,而不是从上到下传递一个打包好的字符串,这个也是需要在开发中 着重明确的,需要在进程类就将所有的成员信息打包,然后不管是组件也好,变量也好,一个成员就对应一个特定的结构,这样是最好的,既能保证整个程序的可拓展性,又能保证整个程序的可维护性和可读性。
4.TCP连接的时候,建立服务器还是客户端进行连接,都不要开vpn,网络可能会被变化,这点要注意。
这个是网络问题,没什么好说的。
之后还发生过一次教师端和学生端之间没法连接的问题,重新编译了一下教师端的netmessage.dll才解决的,具体问题原因不详。
5.做软件的时候,如果有视频,或者有什么单独需要控制的类,可以把 控制单独放在一个蒙版里进行操作,这样就既可以避免一些bug,也可以把模块间的功能划分的清晰一点,这样可以让整个软件的结构更加清晰。
之前是整个软件中控制和 视频放在同一个窗体里进行的,但是这样做不仅效率不高,而且蒙版还极有可能会把视频给挡住(即使蒙版本身是透明的,但是对于非qt的模块来说,没有WA_Translate这个属性的设置依然是完整的窗体,会盖住并停止渲染),所以有时候我们可以做一个单独的窗口来对所有的按钮和操作来进行控制,视频的窗体就安安心心地控制着视频就好了
控制界面蒙版窗体:
视频界面:
但要注意的是:控制界面,或者说蒙版界面应该是视频界面的子窗体(子窗体会永远悬浮在父窗体之上),所以实际上只是蒙版界面在发送一些信号出来给视频界面,实际上的内核操作还是在视频界面,或者说为这个单独的模块,还可以另外再写一个静态类出来,不过只看你是否需要。
6.关于动效,如果刷新频率比较高,且图片大小比较大的时候,QSS图片的刷新可能失效
这点我要说明一下,之前是在那个视频的那一栏进行的头像动效的绘制,不知道是 它这个视频的dll的机制问题,还是我这里写的方法有问题,总之头像动效和视频不能放在同一的主窗体下,否则会导致一些意外的卡顿。
当然也有可能是因为我没加上update();这个方法可以强制重新绘制当前widget,每次刷新stylesheet的时候就可以重新绘制当前widget了。
7.为了避免一些重复引用的情况发生,当我们做一些全局的声明时,请单独用一个.h文件保存起来
比如什么呢?
就比如我们常见的,对SendMessage发送消息码,有时候我们会需要定义一些消息码的名称,有时候我们有需要定义一些指定的数据结构struct,或者无边框窗体最常见的enum Direction{}这样的公共定义,最好不要每次都在自己的.h中定义,这样极容易重复,单独定义一个.h文件,然后需要的时候调用就好了,这样不容易重复定义
比如我们声明一个MSG.h文件来命名一些SendMessage中的内容,UserItem.h文件定义数据结构,Define.h来定义enum等等,或者放在一起,由pragma once保护,会比随意放置安全得多。
8.qt中尽量别用指针,没必要用,qt有一套完善的类stl容器和自我垃圾处理机制,不用单独写一个指针来作为存储对象,尽可能地用QList解决问题
QList