您的位置:首页 > 编程语言 > Qt开发

Qt示例总结

2016-03-28 11:30 387 查看

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  qt qtcreator