主要是java直接调vtk去做三维的mpr太慢了,考虑搭建个网络服务,然后里面直接用c++调 vtk来加速. qt很明显的优点是跨平台.
我首先是直接qt creater 开发的,网络服务用的poco,没有qt前端界面,只是提供http网络服务.用这个开发很恶心的地方有:
(1)debuger 只能看qDbug 的数据变量,
(2)这个编译器支持的编译的是mingw 和msvc系列(这个是我需要的)
(3)qt creater 很容易就崩了
(4) debug和 reasle的切换,需要手动在配置文件中切换相应的依赖,比如 debug依赖的dll后面会带个XXd.dll.不是很方便.
去他的,后面直接用vs2017 加qt插件,像c++那样编译,调试.
下面就是正文开始了,因为是第一次搞qt,时间比较紧,可能很多操作还像小白一样,这里记录一下:
一. 中文乱码问题
失败的: 尝试了网上string 解决中文乱码的问题
成功的: 用qstring解决乱码感觉比string舒服
在main方法中引入
QTextCodec *codec = QTextCodec::codecForName("GBK");
在需要用到中文的地方加上 QString timeStr = QString::fromLocal8Bit("测试"); //注意这个如果编码是utf8 这里要用QString::fromUtf8
然后在写的时候 QByteArray ba1 = timeStr.toLocal8Bit(); //这里同上
DICOMVR_DEBUG(ba1.data());
二.定时器的使用
项目里面会定时清理文件,需要用到定时器.
失败的:首先尝试了Qtime的使用,(网上都是放在qt界面里的,我没有界面),尝试放在main方法里面或者Qthread里面,但是都不能正常使用,或者说不能正常析构(可能是时间不够,我也没有来得及好好分析)
成功的: 用了poco的定时器,操作非常简单
(1)继承public Poco::Util::TimerTask 类键一个自己的定时任务
在里面的run方法中定义自己的逻辑
(2)创建一个 Poco::Util::Timer ,和Poco::Timestamp,在schedule方法中设置启动时间,定时器的时间
三.线程的使用
qt线程里面常用的几种:(1)继承QThread,重载run函数 (2)继承QObject,调用void QObject::moveToThread(QThread *targetThread)(3)QThreadPool and QRunnabl
项目里面要启线程去下载很多文件,启一个线程下载,比较慢 --优化后需要下载的分块下载,比如第一个线程下前100个文件,第二个下100到200.
失败: 我先用的QRunnabl,里面的run去下载文件,url,缓存文件路径都通过构造方法传进去了放在全局里面,但是在执行run的时候,这些全局变量是空的. --- 子线程构造方法是主线程去调用,但是run方法是子线程这样执行的,变量数据就都是空的.
成功:继承的QThread,构造方法里面传全局参数,run里面执行下载逻辑. run执行完了,线程就停止了
使用很简单,继承的类写好之后,在需要使用线程那里, 调用线程的start方法就行
四. 信号和信号槽的使用
qt 里面多了信号,和信号槽的使用. 比如 a执行一项任务, 执行完了发个信号signals, b里面有个信号槽函数slots,会去执行槽函数. 有点像回调了.
整体的使用逻辑是:
(1)a类继承 QObject, 然后在关键字signals下面写信号
(2) b类也继承 QObject, 然后在关键字slots下面写槽函数
(3)在b类构造方法里面用connect 把这些信号和信号槽绑定起来
需要特别注意的是里面最后一项 是链接方法,就是谁去做这个槽函数, 如果是直连, 就是子线程a执行b的槽函数. (失败的例子: 我在主线程执行某个方法需要一直等一个子线程完成然后在继续执行.子线程发信号了,但是 主线程的槽函数一直没有执行. 其实是主线程一直在忙等,收到信号,但是没有执行槽函数,没有把状态修改.)
(4) 在b的方法里面发送信号
(5)信号的参数,可以传参数,也可以不传,信号的参数和槽函数的参数一定要一致,如果是自己定义的类,需要注册
注册之后就可以正常使用了
五.QMap的使用
使用基本 跟java差不多 contains,insert,erase
这里需要特别注意的,如果QMap里面是指针,需要循环删除,最好用迭代器iterator,而且一次之后,需要iter = m_MapProcess.erase(iter);(这里左边不加这个,会出错的)
六. 智能指针的使用
如果很有把握,就可以指针,如果没有把握,就用智能指针
qt项目是特别重视内存泄漏的, 干java干旧了,很多写法不小心就内存泄漏了,项目结束后需要注意检查内存是否有泄漏
七.poco的发送请求
这里有两个场景: (1)访问url,获取检查数据
(2)下载dicom文件
(1)如果你试了网上很多poco的请求方法,还是不行的话,考虑是不是没有开启网络服务
开启之后清理:
::WSACleanup();
(2)如果数据是gzip压缩的(如果是字符串,正常解就行)
需要用到这个 Poco::InflatingInputStream iff(oss, Poco::InflatingStreamBuf::STREAM_GZIP);
(3)如果下载的是文件
(4)最好用try catch 来抓异常,可以看到为什么方法不行