贴一小段最简单的helloworld代码:
#include <QApplication>
#include <QPushButton>
#include <QTranslator>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QTranslator translator;
translator.load("hellotr_la");
app.installTranslator(&translator);
QPushButton hello(QPushButton::tr("Hello world!"));
hello.resize(100, 30);
hello.show();
return app.exec();
}
构建
1) 设置vc的环境变量
cl /?
2)设置qt的环境变量以后
set path=%path%;"c:\\qt\\4.8.6\\bin"
3)调用vc编译器构建
查看了一下安装包里面的二进制depends,发现是使用的共享的vc运行时,所以也用/MD 构建
添加了一个/link /subsystem:windows 和 qtmain.lib避免了运行时出现控制台窗口,
因为qtmain里面实现了一个WinMain函数,这个函数会模拟参数去调用你实现的main函数,因为指定了/subsystem:windows, 这样就不会出现控制台了。
c:\Qt\test>cl /MD /I"C:\\qt\\4.8.6\\include\\qtgui" /I"c:\\qt\\4.8.6\\include" /I"c:\\qt\\4.8.6\\include\\qtcore\\" helloworld.cpp /link /LIBPATH:"c:\\qt\\4.8.6\\lib" /SUBSYSTEM:WINDOWS qtcore4.lib qtgui4.lib qtmain.lib
执行
执行前记得复制几个dll到exe目录,分别是qtcore4.dll qtgui4.dll
课后练习:改改例子
#include <QtGui>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QDialog * dialog = new QDialog(NULL);
dialog->show();
QPushButton *button = new QPushButton("click me", dialog);
QObject::connect(button, SIGNAL(clicked()), &app, SLOT(quit()));
button->show();
button->setStyleSheet(QString("border-image:url(2.jpg)"));
dialog->setStyleSheet(QString("border-image:url(1.jpg)"));
return app.exec();
}
前面2个例子都是太丑陋了,可能无法吸引初学者的脚本,来个ui文件自动加载的,
ui文件实际上就是一个xml模板,上面我们已经知道qt支持qss,样式表。
联想起来,简直就是html+css的natvie版本嘛,那好了,从此做界面什么也不差了,就差你的想象力和美工了。ok?
#include <QtGui>
#include <QtUiTools>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QUiLoader loader;
QFile file("untitled.ui");
file.open(QFile::ReadOnly);
QWidget *formWidget = loader.load(&file, NULL);
file.close();
formWidget->show();
return app.exec();
}
ui文件自己去定义吧,或者用qtdesigner去画吧。
接下来,作者打算研究qt最核心的signal和slot机制了,只要再搞清楚了这个,qt开发就可以启程了。
备注:
关于资源文件的问题?
qt提供了*.ui文件定义控件的布局等,qss文件定义控件的样式,qrc文件打包零散的资源文件(icon, 字符串,images等),
可以在ui文件里面直接引用文件系统的image路径,也可以在qss里面直接引用image的文件路径,但是都要保证运行时候这些image都在文件系统里面可以找到,
如果使用qrc文件,需要编译时候使用rcc打包,
rcc -o myres.rcc -binary myres.qrc
这个时候,rcc会搜索所有的列表在qrc里面的资源,把他们打包到一起。
需要你在程序的一开始注册一下这个rcc资源,程序就知道还有一个虚拟的目录(rcc文件展开的虚拟目录)可以用来搜索资源了。
QResource::registerResource("myres.rcc");
然后你loadui或者直接访问border-image:url(...)就可以在rcc文件里面搜索了。
但是要保证rcc文件和运行程序放置在同一个目录下。
个人感觉这中一个程序带一个rcc的方式比较丑陋,还不如直接零散的放置到exe所在的目录res目录下。
rcc还可以包qrc资源文件编译成c++源文件,把图片等用静态数组的方式定义,然后编译链接到二进制程序中。
debug\qrc_utitled.cpp: ..\untitled\utitled.qrc \
..\untitled\images\1.jpg
c:\Qt\4.8.6\bin\rcc.exe -name utitled ..\untitled\utitled.qrc -o debug\qrc_utitled.cpp
uic也可以将ui定义的模板编译成头文件,供管理这个ui的类嵌入
ui_widget.h: ..\untitled\widget.ui
c:\Qt\4.8.6\bin\uic.exe ..\untitled\widget.ui -o ui_widget.h
比如向导建立的常见例子中,有个Widget类,和一个widget.ui,那么,生成一个ui::widget的类放在ui_widget.h里面,
然后Widget类,可以声明一个private的ui::widget ui变量来管理ui界面。
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
void reTranslate();
private:
Ui::Widget *ui;
};
还差什么文件类型没有解释的?
moc文件,ts文件。
任何在pro文件的头文件列表里面指定的头文件,如果包含有Q_OBJECT等moc宏的话,qmake会生成一个make规则,告知moc处理一下头文件,生成moc_xxxx.cpp 主要是一下帮助对象在运行时知道自己是什么类型的辅助信息。
也就是java和c#等脚本语言的反射功能。这些功能主要用于signal和slot连接的一些功能。
ts文件,是翻译文件的模板,一个xml文件,如果在
使用lupdate处理一下项目源文件搜索所有的 tr("xxxx")指定的字符串,并输出到指定的ts文件,这个ts文件位置可以从pro文件获取到,也可以手动-ts 指定。
使用lrelease把翻译好的.ts文件压缩成.qm文件,这个qm文件可以在程序开始的时候load,或者你任何你需要的时候load,但是load完成以后,一定要记得有类似的retranslate()更新操作。
如果翻译文件叫做zh_CN.qm:
Widget w;
w.show();
w.setWindowTitle(QTranslator::tr("Hello")); // 不现实翻译
QTranslator * translator = new QTranslator(&a);
if (translator->load("zh_CN")){ // 加载翻译
a.installTranslator(translator); // 安装翻译
}
w.reTranslate(); // 界面会被翻译更新
void Widget::reTranslate()
{
ui->retranslateUi(this);
}
void retranslateUi(QWidget *Widget)
{
Widget->setWindowTitle(QApplication::translate("Widget", "Widget", 0, QApplication::UnicodeUTF8));
label->setText(QString());
pushButton->setText(QApplication::translate("Widget", "PushButton", 0, QApplication::UnicodeUTF8));
} // retranslateUi