Qt示例总结

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)