Browsed by
标签:qt

装机 – Ubuntu16.04

装机 – Ubuntu16.04

老婆公司有个让人惊讶的规定:员工笔记本三年后归自己个人所有,公司重新配新电脑! 这是多么让人热爱的公司!老婆工作这几年,家里多了几台笔记本,一水的ThinkPad。上周又过了三年,拿回一台T430。以前拿回电脑时,会恢复到Thinkpad出厂时安装的window系统,这次这台T430居然只是低格了,没有系统?!

当然可以从网上扒一个windows恢复盘下来重装,不过考虑到家里已经有几台windows的笔记本和台式机,实在没有必要再增加一台,因此这次打算装Linux系统试试。

选择发行版本

“Linux发行版本”之争在程序员迷之争论中绝对可以位列前三位!好在是给自己的笔记本选发行版,因此有幸避免了与别人的争论,只要考虑自己的需求就好了。我的基本原则其实很简单:

(1)发行版要有强大的、历史悠久的社区。

(2)或者,有商业背景企业发布的版本。

以上两点只确保一个问题:若干年后,依然能活着并得到强有力的支持。绝大多数妖艳的Linux发行版本,比如Arch等,基本不用考虑了。符合要求的版本大致也就是:Debian、CentOS、Ubuntu等寥寥数种而已。

CentOS的软件实在太老旧了点,有时候不得不自己去编译各类软件,与其这样,还不如用Arch或者Gentoo等版本来得直接。公司做项目时基本都是采用Debian系统做服务器,很满意,但是Debian桌面系统就差强人意。不知道是Debian的问题,还是KDE的问题,使用时总有各种烦人的小毛病,比如鼠标问题等。

因此这次就选择了Ubuntu 16.04 (Unity7),谁会做死去选择Ubuntu的非LTS版本呢?

安装软件

安装Ubuntu系统实在没什么可以说的,下载iso文件,录制u盘,直接安装即可,比装windows还简单,过程枯燥乏味。下面只是记录一些安装应用软件方面需要注意的地方。

安装virtualBox与Windows环境下稍有不同,扩展功能包也收录在软件中心,因此实际执行命令一起安装:

sudo apt-get install virtualbox virtualbox-ext-pack

将其他计算机中的vbox客机导出到新计算机中,U盘必须采用exFat格式才能支持超过4G大小的文件,ubuntu默认没提供对该格式的支持,因此也需要单独安装:

sudo apt-get install exfat-utils

qt开发工具集升级到qt5了,采用以下命令安装:

sudo apt-get install qt5-default
掉坑里了

掉坑里了

Qt无疑是个非常好的framework,我们一直用TA。虽然不敢说已经是行家里手,不过好歹也开发这么久程序了,渐渐地有些自负起来,因此掉坑里了。

坑来自Qt最经典的设计:signal-slot。我以前的理解这是异步的,常用于模块间解耦。在windows平台,这个理解似乎没错,signal-slot底层依赖window的message机制。而在linux平台,其实现方式默认仍然是callback机制。

callback机制在多线程编程里最容易出问题的就是“锁”。这次掉坑里,就是在slot中应用“锁”时不小心,导致了死锁。

这次竟然忘了这点! :-(

qt network中的一点问题

qt network中的一点问题

在一个小应用中使用了qt的network模块,调用网站的一个接口(HTTP GET方式),获得相应的结果。操作非常简单,可是却出现了问题。

首先是在windows上,运行程序后,提示无法定位libeay32.dll。这个是openSSL的动态链接库,不明白为什么qt4.8.5(windows)默认链接了这个库。查看文档,貌似缺省情况下是不编译进SSL功能的,而且我们用的包并不是自己编译的,是直接从qt网站下载安装的。解决方法也简单,无非就是安装openssl的库,copy相应的dll到exe文件同一目录下即可。

接着又出现了问题,调用HTTP后,服务器返回“406 NOT acceptable”。直接将链接放在浏览器中执行又没有任何问题。检查server上的log,发现apache启动了ModSecurity模块,该模块检查了User-Agent头,如果太简单则认为是假请求(spam请求?),拒绝该HTTP请求。

用wireshark抓了一下包,发现QNetworkRequest默认的User-Agent的确非常简单:

User-Agent: Mozilla/5.0

解决方式同样简单,我们强行修改为稍微复杂一点即可,例如:

QNetworkRequest netReq;
netReq.setUrl(destUrl);
netReq.setRawHeader("User-Agent","Mozilla/5.0 (X11; Linux x86_64)");

这样就可以绕开apache模块的检查。

qt编译中抑制特定告警信息

qt编译中抑制特定告警信息

在编译某些代码时,我们希望抑制掉一些VC的编译告警,例如C4244(丢失精度告警)。我们可以直接修改mkspecs目录下对应的配置文件,但这样做会影响到所有工程,而我们实际上只希望对某些特定的工程关闭该告警。

可以直接修改pro文件,加入以下内容即可:

QMAKE_CFLAGS += /wd4244

如果是cpp文件,则指定以下参数即可:

QMAKE_CXXFLAGS += /wd4244
Phonon程序无法播放语音文件的问题

Phonon程序无法播放语音文件的问题

问题基本情况如下:我们开发并发布了一个软终端产品,当然其中采用QT以及Phonon模块。在我们的开发环境中,一切都很美好,能正常地播放音乐。可是安装到客户的计算机上,出现问题了,无法播放提示语音(wav文件录制)。

这个问题的实质是我们没有将Phonon的插件一同打包进安装文件。Phonon实质上只是个前端封装模块,具体工作有赖于后台的解码器。在windows系统中,Phonon缺省采用DirectX作为后台解码器部分,具体实现为一个plugin。如果不安装这个plugin,则phonon无法正常播放语音文件。

假设QT安装在d:\qt\4.8.4目录下,则上述plugin可以在以下目录中找到:D:\Qt\4.8.4\plugins\phonon_backend\phonon_ds94.dll。

注意,不是简单地将这个文件拷贝到程序目录下即可,而是要拷贝到程序目录的phonon_backend子目录下。例如,我们的程序安装在d:\minisipphone目录,则上述dll应当拷贝为:d:\minisipphone\phonon_backend\phonon_ds94.dll。

另外需要注意的是,不同版本的QT要采用各自版本的phonon_ds94.dll,例如qt 4.6.2的程序就不能采用qt 4.8.4的phonon_ds94.dll,否则还是会出现放音错误。

QT程序自动重启

QT程序自动重启

一行代码就可以了:

// restart application
QProcess::startDetached(qApp->applicationFilePath(), QStringList());
QT程序与gprof

QT程序与gprof

gprof能分析出函数的调用关系以及占用时间,对分析程序性能瓶颈很有帮助。

在采用QT开发时,如果程序分成若干个库,那么仅仅在编译时加入-pg选项是不能产生gmon.out文件,还必须在链接选项中也加入-pg才可以。在pro文件中做如下设置即可:

QMAKE_CXXFLAGS += -pg
QMAKE_LFLAGS += -pg

让人比较郁闷的是,gprof不支持动态链接库和Multi-Thread程序。这实在是非常大的局限。

修改QT的编译开关

修改QT的编译开关

linux系统环境的qmake工具生成的makefile文件,缺省没有打开优化开关-o2,我们可以修改pro文件来打开这个开关,如下:

unix {
QMAKE_CXXFLAGS += -o2
}

如果是采用gcc编译,则需要根据版本情况,设置QMAKE_CFLAGS_RELEASE或者QMAKE_CFLAGS_DEBUG即可。

以上配置基于Kubuntu 11.04环境。

QT与KDE的版本对应关系

QT与KDE的版本对应关系

两者貌似基本是对应的。例如QT3.x出来后,KDE也升级为3.x;QT4.x出来后,KDE紧随其后也升级为4.x。

照这个比对,QT下个版本应该是QT5.x,然后KDE也升级为KDE5.x。。。

然而,现在Nokia将QT魔幻般地变回QT SDK 1.0!

KDE是不是该抓狂了?:-)

QT SDK与C4100编译告警

QT SDK与C4100编译告警

“warning C4100: … unreferenced formal parameter.”

QT SDK (VC2008)在使用qmake生成makefile文件时,缺省会打开C4100的编译告警开关。就我们的开发实践来说,C4100实在是个多余的告警,尤其是在C++程序中,我们经常定义一些虚函数等作为接口类,这些虚函数本身基本是空函数,由派生类重载出具体的实现。一旦放开C4100告警,VC编译器就看这些函数中没有引用的形参非常不爽,频频给出告警,实在是烦人。

我们可以在头文件中要求编译器忽略C4100告警:

#pragma warning( push )

#pragma warning( disable : 4100 )

void fun1(…){}

#pragma warning( pop )

这样做也有不好的一面,我们不得不修改.h文件,包括一些第三方库的头文件。另外,这似乎也破坏了跨平台的特性,和VC编译器绑定过紧(?不清楚其他编译器,例如gcc,是否也支持这种预处理指令)。

我们决定直接关掉C4100告警,修改以下文件(qt安装在d:\qt\4.6.2目录):

D:\Qt\4.6.2\mkspecs\win32-msvc2008\qmake.conf

在这个文件中,找到QMAKE_CXXFLAGS_WARN_ON,将它后面的-w34100删除掉。

然后回到自己的工程,重新用qmake生成makefile,此时再编译,就不会有C4100告警了。