Qt5的例子在哪里
最近刚用qt5.3.0+VS2013去开发程序,突然发现,qt以前自带的例子咋找不到了呢?
但在安装目录里是有的啊,见C:\Qt\Qt5.3.0\Examples。
最后才发现貌似安装后的开始目录里,已经没有了当年经常看到的《Qt Examples Launcher》快捷方式
,也没有了这个应用程序。
qt5.3
qtcreator
1
仔细找了找,原来qt已经把所有的例子融合在qtcreator中。以前一直用VS和qt开发,没咋用qtcreator
。
Qt5的例子在哪里?
2
打开qtcreator,在欢迎界面就能看到所有examples。它的列表展现方式也比以前更加直观了。
========
Qt实现应用程序单实例运行--LocalServer方式
使Qt应用程序能够单实例运行的典型实现方法是使用共享内存实现。该方法实现简单,代码简洁。
但有一个致命缺陷:共享内存(QSharedMemory)实现的单程序运行,当运行环境是UNIX时,并且程序不
幸崩溃,会导致共享内存无法释放,从而无法重新运行程序!
所以应该寻找其他的使Qt应用程序能够单实例运行的方案。于是找到LocalSocket和LocalServer通讯方
案(据说Qt官方商业版的QSingleApplication的原理好像跟这个差不多)。
“要用到Qt的QLocalSocket,QLocalServer类,这两个类从接口上看和网络通信socket没有区别,但是
它并不是真正的网络API,只是模仿了而已。这两个类在Unix/Linux系统上采用Unix域socket实现,而在
Windows上则采用有名管道(named pipe)来实现。”
参见:
http://www.oschina.net/code/snippet_54100_629
http://blog.csdn.net/qq19831030qq/article/details/6199896
上面的方案实际操作过程中出现很多问题:
QString serverName = QCoreApplication::applicationName(); //获取到的serverName为空
为了解决上面的问题,最直接的测试方法是先手动指定一个serverName,
然后将QFile::remove(m_localServer->serverName());改成QFile::remove(serverName);
当手动指定serverName时,习惯上将serverName设为当前的应用程序名,在linux下这又导致下面的问题
QFile::remove(m_localServer->serverName()); //执行删除失败(实际测试发现失败原因是:尝试删除
应用程序文件自身!)
上面的两个问题导致Qt应用程序无法单实例运行。
后来终于在StackOverflow上面看到解决方案:使用QLocalServer::removeServer()删除LocalServer名
下面是实现代码:
头文件:
复制代码
1 #ifndef SINGLEAPPLICATION_H
2 #define SINGLEAPPLICATION_H
3
4 #include <QObject>
5 #include <QApplication>
6 #include <QtNetwork/QLocalServer>
7 #include <QWidget>
8
9 class SingleApplication : public QApplication {
10 Q_OBJECT
11 public:
12 SingleApplication(int &argc, char **argv);
13
14 bool isRunning(); // 是否已經有实例在运行
15 QWidget *w; // MainWindow指针
16
17 private slots:
18 // 有新连接时触发
19 void _newLocalConnection();
20
21 private:
22 // 初始化本地连接
23 void _initLocalConnection();
24 // 创建服务端
25 void _newLocalServer();
26 // 激活窗口
27 void _activateWindow();
28
29 bool _isRunning; // 是否已經有实例在运行
30 QLocalServer *_localServer; // 本地socket Server
31 QString _serverName; // 服务名称
32 };
33
34 #endif // SINGLEAPPLICATION_H
复制代码
CPP文件:
复制代码
1 #include "SingleApplication.h"
2 #include <QtNetwork/QLocalSocket>
3 #include <QFileInfo>
4
5 #define TIME_OUT (500) // 500ms
6
7 SingleApplication::SingleApplication(int &argc, char **argv)
8 : QApplication(argc, argv)
9 , w(NULL)
10 , _isRunning(false)
11 , _localServer(NULL) {
12
13 // 取应用程序名作为LocalServer的名字
14 _serverName = QFileInfo(QCoreApplication::applicationFilePath()).fileName();
15
16 _initLocalConnection();
17 }
18
19
20 ////////////////////////////////////////////////////////////////////////////////
21 // 说明:
22 // 检查是否已經有一个实例在运行, true - 有实例运行, false - 没有实例运行
23 ////////////////////////////////////////////////////////////////////////////////
24 bool SingleApplication::isRunning() {
25 return _isRunning;
26 }
27
28 ////////////////////////////////////////////////////////////////////////////////
29 // 说明:
30 // 通过socket通讯实现程序单实例运行,监听到新的连接时触发该函数
31 ////////////////////////////////////////////////////////////////////////////////
32 void SingleApplication::_newLocalConnection() {
33 QLocalSocket *socket = _localServer->nextPendingConnection();
34 if(socket) {
35 socket->waitForReadyRead(2*TIME_OUT);
36 delete socket;
37
38 // 其他处理,如:读取启动参数
39
40 _activateWindow();
41 }
42 }
43
44 ////////////////////////////////////////////////////////////////////////////////
45 // 说明:
46 // 通过socket通讯实现程序单实例运行,
47 // 初始化本地连接,如果连接不上server,则创建,否则退出
48 ////////////////////////////////////////////////////////////////////////////////
49 void SingleApplication::_initLocalConnection() {
50 _isRunning = false;
51
52 QLocalSocket socket;
53 socket.connectToServer(_serverName);
54 if(socket.waitForConnected(TIME_OUT)) {
55 fprintf(stderr, "%s already running.\n",
56 _serverName.toLocal8Bit().constData());
57 _isRunning = true;
58 // 其他处理,如:将启动参数发送到服务端
59 return;
60 }
61
62 //连接不上服务器,就创建一个
63 _newLocalServer();
64 }
65
66 ////////////////////////////////////////////////////////////////////////////////
67 // 说明:
68 // 创建LocalServer
69 ////////////////////////////////////////////////////////////////////////////////
70 void SingleApplication::_newLocalServer() {
71 _localServer = new QLocalServer(this);
72 connect(_localServer, SIGNAL(newConnection()), this, SLOT(_newLocalConnection()));
73 if(!_localServer->listen(_serverName)) {
74 // 此时监听失败,可能是程序崩溃时,残留进程服务导致的,移除之
75 if(_localServer->serverError() == QAbstractSocket::AddressInUseError) {
76 QLocalServer::removeServer(_serverName); // <-- 重点
77 _localServer->listen(_serverName); // 再次监听
78 }
79 }
80 }
81
82 ////////////////////////////////////////////////////////////////////////////////
83 // 说明:
84 // 激活主窗口
85 ////////////////////////////////////////////////////////////////////////////////
86 void SingleApplication::_activateWindow() {
87 if(w) {
88 w->show();
89 w->raise();
90 w->activateWindow(); // 激活窗口
91 }
92 }
复制代码
调用示例:
复制代码
1 #include "MainWindow.h"
2 #include "SingleApplication.h"
3
4 int main(int argc, char *argv[]) {
5 SingleApplication a(argc, argv);
6 if(!a.isRunning()) {
7 MainWindow w;
8 a.w = &w;
9
10 w.show();
11
12 return a.exec();
13 }
14 return 0;
15 }
========
神奇的qt creator 例子程序
这是qt creator第一个例子程序,名叫application,简单的记事本一类的程序.
1.奇怪的是没有.ui文件,资源里就一些png文件.界面怎么拼出来的?
2.MainWindow里实现了所有的关于这个记事本的操作,保存文件之类的.但是在哪里调的?为什么按那个"
保存"按钮,就能调到这个函数,找不到调用的地方,用find reference也找不到.
.......你用过其它IDE么。。
界面上控件可以在设计器上拖上来,也可以在代码里直接实现。
先简单看一下教程再看例子吧
在哪个文件里?所有文件都列出来了
都在createActions函数里.
Qt编程没说一定要ui文件,好多程序都是手敲界面的
========
Qt-简单程序实例Hello,world
D:\Qt_Work\hello\main.c:
1 #include <QApplication>
2 #include <QWidget>
3 #include <QPushButton>
4
5 int main(int argc, char *argv[])
6 {
7 QApplication a(argc, argv);
8 QWidget MainWindow;
9 MainWindow.setMinimumSize(200, 100);
10 MainWindow.setMaximumSize(200, 100);
11
12 QPushButton button("Hello, World", &MainWindow);
13 button.setGeometry(20, 20, 160, 60);
14 MainWindow.show();
15 return a.exec();
16 }
分析一下程序:
main()程序入口函数。
程序首先创建了一个QApplication类对象。Qt程序中只能包含一个QApplication对象。argc和argv也用
作QApplication对象构造函数参数。
接下来新建了一个QWidget对象。QWidget可以看作一个窗口。在其上可以放置其他对象。如按钮等。
第9行和第10行将MainWindow的最小尺寸和最大尺寸设置为一样。这就意味着此窗口不可以调节。
第12行创建了一个按钮对象button,并且直接调用QPushButton的一个构造函数。第一个参数告诉构造函
数将按钮的标签设置为"Hello, World"。第二个参数使MainWindow作为按钮的父窗口,这意味着将按钮
放置在 MainWindow窗口上。
第13行设置按钮的尺寸。前两个参数告诉按钮的左上角在其父窗口的位置,他们相对于父窗口的左上角
。后两个参数设置按钮的宽度和高度(这里是160像素宽,60像素高)。
第14行调用MainWindow的show()函数。用来显示窗口。这里不必调用button的show()函数。因为当其父
窗口被调用显示时,button会被自动显示。
第15行将控制权从main()函数交给Qt。在exec()函数中,Qt接受和处理用户以及系统事件,并把这些事
件传递给相应的窗口。当应用程序关闭时,exec()函数返回.
========
QT 信号与槽 最简单例子
main.cpp 和 my_head.h源码:
#ifndef MY_HEAD_H
#define MY_HEAD_H
#include <stdio.h>
#include <QObject>
//EastonWoo
class A : public QObject //QObject::connect是在QObject定义的,继承一下。 <span
style="color:#ff0000;">注意: 如果类A 本身就已经继承过QObject了,就不用再继承了,你可以这样
查看是否已继承过:把光标移动到类A,右键,选择"Open Type Hierarchy",或直接按Ctrl+Shift+T,就
可以查看到类的继承关系了。</span>
{
Q_OBJECT //信号和槽要用到的宏,要加上
public:
void test()
{
send_msg();
}
signals: //信号关键字
void send_msg(); //发射信号函数,带的参数必须和槽一样。声明一下就可以了。
};
class B : public QObject
{
Q_OBJECT
public slots: //槽关键字
void recv_msg() //
{
printf("hello\n");
}
};
//值得注意的是,凡是信号和槽的定义关键字都在头文件里定义
//如Q_OBJECT,signal:,public slots:,声明如void send_msg();void recv_msg();
#endif // MY_HEAD_H
#include "my_head.h"
//EastonWoo
int main()
{
printf("start...\n");
A send_a;
B recv_b;
QObject::connect(&send_a,SIGNAL(send_msg()),&recv_b,SLOT(recv_msg()));
send_a.test();
return 0;
}
qmain一下:
运行结果:
/home/user/hello/hello 启动中...
start...
hello
/home/user/hello/hello 退出,退出代码: 0
{1 ?}
========
QT范例解析
QT动画
在QT自带的demo中,有个一个2dpainting的范例,这个例子可以很好的阐述QT简单的动画效果机制。在
main函数中创建一个Window对象实例,这个类是从QWidget继承来的,其构造函数中创建一个Widget类型
对象,并创建一个QTimer对象,每隔50毫秒触发一次Widget对象的animate()槽函数。在animate中设置
一个累计计数变量elapsed,每次被触发增加50(QTimer的触发间隔)并膜上1000,保证这个值不超过
1000.而后调用repaint()函数触发调用paintEvent()函数,再次进行绘制即可。
void Widget::paintEvent(QPaintEvent *event)
{
//The QPainter class performs low-level painting on widgets and other paint devices
//QPainter类在Widget或其他绘制设备上执行底层的绘制操作
QPainter painter;
painter.begin(this);//开始在设备上绘图 一个设备上只能有一个绘制对象
painter.setRenderHint(QPainter::Antialiasing);//设置反锯齿
helper->paint(&painter, event, elapsed);//绘制
painter.end();
}
void Helper::paint(QPainter *painter, QPaintEvent *event, int elapsed)
{
painter->fillRect(event->rect(), background);
painter->translate(100, 100);//移动画板中心 使widget的中心点为原点
//设置保存点
painter->save();
painter->setBrush(circleBrush);//设置画刷
painter->setPen(circlePen); //设置画笔
painter->rotate(elapsed * 0.030); //按角度顺时针旋转设备 使画面看起来是动的
qreal r = elapsed / 1000.0; //设置微调 r的值从0到1.0循环
int n = 30;
//画30个圆圈
for(int i = 0; i < n; ++i){
painter->rotate(30); //旋转设备30度 绘制圆
qreal radius = 0 + 120.0 * ((i + r) / n);
qreal circleRadius = 1 + ((i + r) / n) * 20;//半径
painter->drawEllipse(QRectF(radius, -circleRadius, circleRadius * 2, circleRadius *
2));
}
painter->restore();
painter->setPen(textPen);
painter->setFont(textFont);
painter->drawText(QRect(-50, -50, 100, 100), Qt::AlignCenter, "QT");
}
QT绘图提供了一个很好的机制,在绘制过程中,要绘制的图具有不同位置和旋转角度,但只需要平移和
旋转画板对象(绘画设备),实现坐标映射后,在映射后的坐标的原点位置绘制图形,从而简化了对图
形位置和角度的计算。
QML与类实例化
QT提供了QML机制,可用于设计界面,但qml也可以实现类对象的持久化。adding范例中定义了一个从
QObject继承的类Person,使用Q_OBJECT宏声明,并使用Q_PROPERTY宏定义了两个属性name和shoeSize.这
样就可以使用QT的反射机制从qml中加载类的属性了.在main函数中调用qmlRegisterType模板函数注册
Person类并指定其版本号和qml中的库名称People.这样就可以从一个合法的qml文件中加载Person类实例
了.
QML文件内容(格式类似于json):
import People 1.0
Person{
name: "Henreash"
shoeSize: 12
}
注册并创建实例:
qmlRegisterType<Person>("People", 1, 0, "Person");//将类person注册到qml中,注册类名为People
在qml中使用People标签定义person类对象
QDeclarativeEngine engine;//QDeclarativeEngine为实例化QML组件提供一个环境
QDeclarativeComponent component(&engine, QUrl
("qrc:/adding/example.qml"));//QDeclarativeComponent封装了QML组件的定义,是一个数据提供者
Person *person = qobject_cast<Person *>(component.create());//使用导入的qml组件创建对象
并做类型转换
if(person)
qWarning() << "The person's name is " << person->name();//使用导入的对象属性
========
相关链接
http://www.cnblogs.com/hicjiajia/category/350988.html
http://blog.csdn.net/liang890319/article/details/7250244