找回密码
 FreeOZ用户注册
查看: 13036|回复: 122
打印 上一主题 下一主题

[菜鸟学堂] qt学习笔记

[复制链接]
跳转到指定楼层
1#
发表于 8-1-2009 10:04:35 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?FreeOZ用户注册

x
回国前开始想学习qt,因为底子太差,很多基础的东西都不懂,先补习了一下c++(原来只看过一遍谭浩强,没实际编过程序),然后发现有些东西比如gcc等都跟linux关系很密切,没接触过linux的我经常看得一头雾水,又转头去从0开始学习linux,回了国以后,天天灯红酒绿,就扔一边了,现在回来重新开始。

现在开始跟着tutorial一步一步学习。把学习过程在这里记录一下,主要也是让大家也监督一下,要不自己容易偷懒。

扔了2个月,倒好像突然开了点窍,之前一直没能想明白的一个问题,现在突然明白了。回国前我用eclips+qt design,作了几个试验,发现在环境中都能运行,但是如果我从windows里面单独运行,总是说找不到dll文件,想了很久没相通。 今天直接用文本编辑器把那个就一个按钮的hello world写了一下,然后从命令行编译,运行,成功了!后来我从windows里面试图运行,结果又出现了同样的没有dll的错误信息,这时候我突然醒悟,原来是环境设置的问题,在命令行窗口,初始化时已经自动设置了路径,但是从windows里面直接运行,则缺少了这个设置,于是就找不到文件了。gcc的编译,似乎并不能把所有需要的库函数放到一个可执行文件里,所以存在着一个路径设置的问题。不知道linux下面是什么情况,以后用到再说吧。

顺便说一下,各位高人看到我有什么理解错误的地方,请及时给我指出来啊

评分

参与人数 1威望 +30 收起 理由
coredump + 30 谢谢分享!坚持下去!

查看全部评分

回复  

使用道具 举报

2#
 楼主| 发表于 8-1-2009 11:06:25 | 只看该作者
放错地方了,麻烦斑竹给挪到软件那里吧
回复  

使用道具 举报

3#
发表于 8-1-2009 13:00:15 | 只看该作者
你把qt和gcc按照bin的这个目录路径 加到windows环境变量path去, 就可以直接运行了。

linux下面也是一样的,都是加到用户的环境变量里面去。 当然linux下面用lib(.a)文件有时要指定。
回复  

使用道具 举报

4#
发表于 8-1-2009 13:03:59 | 只看该作者
我搞不懂lz为何要学qt呢, qt粉丝不要打我, 我觉得现在都是java, .net大行其道, 至少我认为在这里悉尼没有很多, 几乎没有。
回复  

使用道具 举报

5#
 楼主| 发表于 8-1-2009 15:37:13 | 只看该作者
原帖由 migao21 于 8-1-2009 14:03 发表
我搞不懂lz为何要学qt呢, qt粉丝不要打我, 我觉得现在都是java, .net大行其道, 至少我认为在这里悉尼没有很多, 几乎没有。



一直想学习pc上的编程,曾经学习了一段时间的delphi,结果学了以后发现根我工作中的c混到了一起,c程序里经常冒出delphi的句子来,反过来也是,把自己搞晕了,就没再继续。后来决定还是c++吧,起码差不多。又跟着c++ builder走了一阵,但发现这个只能在windows下用,我的目标是嵌入式,还是linux有用一些,qt跨平台,正好适合我。


顺便做个笔记:

看到第5章了,可以用继承QWidget的方式自己定义一个类(window),然后把button等等东西都放在里面(在构造函数里面定义,parent widget是this, 使用new)
qApp是一个QApplication头文件里定义的全局变量,指向这个QApplication的对象(QApplication对象是每个程序必须有的,main函数里面第一句就是定义这个对象),qApp可以在任何地方使用,从而可以做到使用任何一个按钮作为程序的退出按钮。

疑问:如果定义2个QApplication对象会有什么结果? 比如分别为 App1和App2, 现在标准程序里面 main函数最后一句是 return App1.exec(); 如果还有个 App2, 在return语句之前, 加个 App2.exec();, 会有什么结果?

试了一下,程序如下:
int main (int argc, char * argv[])
{
        QApplication App(argc, argv), App2(argc, argv);
        ....(省略)
App2.exec();
        return App.exec();
}
编译能通过,一运行报告一个runtime error, "This application has requested the Runtime to terminate it in an unusual way. Please contact the application's support team for more information"

看来只能有一个,我就不管为什么了,不是我这初级选手关心的问题,感兴趣的高手可以告诉俺一下。

[ 本帖最后由 四香油饼 于 8-1-2009 16:43 编辑 ]
回复  

使用道具 举报

6#
发表于 8-1-2009 16:05:11 | 只看该作者
我也不懂QT,但是看你上面这段说明,感觉是你在一个程序里面定义并使用两个QApp导致发生错误,就像你要往一个蚂蚁窝里面放两只蚁后也会出乱子一样。
回复  

使用道具 举报

7#
发表于 8-1-2009 16:45:03 | 只看该作者

回复 #5 四香油饼 的帖子

QApplication 这样的类是典型的Singleton Pattern的实现,目的就是防止你这类的突发奇想的用法的

参考:qt\src\corelib\kernel\qcoreapplication.h 里有个
class QCoreApplication
{
...
static QCoreApplication *instance() { return self; }
...
}

而QApplication是从QCoreApplication继承来的。

多看看QT的源代码,就明白了。QT源代码里几乎包含了所有经典Design Pattern的实做,静下心来研究会获益匪浅的

有一本书,专门结合QT4的源代码探讨C++设计模式实现和应用的,LZ不妨一读。
回复  

使用道具 举报

8#
发表于 8-1-2009 16:47:06 | 只看该作者
现在考你一下,你说那个报错是你第一个QApplication.exec()报的还是后一个报的,为什么报这样的错误? 如果不看代码,不调试就能知道原因,你就真正理解QApplication的实现原理了。
回复  

使用道具 举报

9#
发表于 8-1-2009 17:22:54 | 只看该作者
原帖由 migao21 于 8-1-2009 13:03 发表
我搞不懂lz为何要学qt呢, qt粉丝不要打我, 我觉得现在都是java, .net大行其道, 至少我认为在这里悉尼没有很多, 几乎没有。

这不矛盾的, C++, Java, C#各有各的应用领域。

对于QT来说,学它的目的可以是:

1. 开发手机应用
    Nokia收购了QT,并且移植到了S60系统上,此外Trolltech原来就有个基于Linux的Qtopia嵌入式平台(现在叫QT Extented)。Nokia最新的高端手机N97(http://www.freeoz.org/forum/redirect.php?fid=7046&tid=810290)里大量采用了QT进行开发。
2. Linux,Open Source开发
    如果在Linux下开发GUI程序的话,KDE, QT怎么能够不好好学习呢。
3. 大量的企业专业应用软件使用QT开发的
    http://trolltech.com/qt-in-use
    比如Mathematica , Google Earth, 西门子大量工控软件(http://trolltech.com/qt-in-use/story/customer/siemens), 一些高级复杂的可视化专业软件,如 MAYA等。如果需要开发类似系统,那么QT,C++必须非常精通。
4. 很多游戏的前端使用QT开发的

blablabla...
回复  

使用道具 举报

10#
 楼主| 发表于 8-1-2009 18:17:37 | 只看该作者
原帖由 coredump 于 8-1-2009 17:47 发表
现在考你一下,你说那个报错是你第一个QApplication.exec()报的还是后一个报的,为什么报这样的错误? 如果不看代码,不调试就能知道原因,你就真正理解QApplication的实现原理了。


我其实不懂,你给的连接我也没看,觉得我现在应该集中精力能用起来再说,kernel的东西以后有时间需要提高水平的时候再慢慢学习。我瞎猜一个,应该是第一个吧?第二个生成的时候要求第一个终止,对于第一个相当于是受到外力的作用被迫中止,于是就报错了。
回复  

使用道具 举报

11#
发表于 8-1-2009 18:27:08 | 只看该作者

回复 #10 四香油饼 的帖子

非也。
第一个是自然终止的,正常结束。因为QApplication是单例模式的类,所以系统里只能有一个QApplication 实例,第一个和第二个其实都是同一个对象(不止两个,声明多少个QApplication其实系统里只有一个实例)。exec()本身也是个静态函数,这个函数结束后QApplication的这个唯一实例会被销毁,这样第二个exec()再执行时会发现那唯一的一个QApplication对象已经不见了,所以会报这样的错,这就是错误信息的 unusual way的含义。

不过你换个写法,程序就应该能够通过了:
        QApplication App1(argc, argv);
        App1.exec();
        QApplication App2(argc, argv);
        App2.exec();
回复  

使用道具 举报

12#
 楼主| 发表于 8-1-2009 18:58:32 | 只看该作者
原帖由 coredump 于 8-1-2009 19:27 发表
非也。
第一个是自然终止的,正常结束。因为QApplication是单例模式的类,所以系统里只能有一个QApplication 实例,第一个和第二个其实都是同一个对象(不止两个,声明多少个QApplication其实系统里只有一个实例)。e ...



俺的理解,这是不是相当于程序运行了2次?第二个app只有在第一个结束之后才会运行
回复  

使用道具 举报

13#
发表于 8-1-2009 19:52:28 | 只看该作者

回复 #12 四香油饼 的帖子

看看结果就知道了
回复  

使用道具 举报

14#
 楼主| 发表于 8-1-2009 23:08:15 | 只看该作者
试了,可以运行,但是退出的时候还是报那个错误。
回复  

使用道具 举报

15#
发表于 8-1-2009 23:16:32 | 只看该作者

回复 #14 四香油饼 的帖子

一般这样的错误都是内存操作引起的,比如一块内存被释放2次之类的,你用debug版运行,然后就能定位到位置了。QApplication类里面有很多的初始化细节,  不同平台上结果可能也不一样。

不过,源码面前,了无秘密
回复  

使用道具 举报

16#
 楼主| 发表于 8-1-2009 23:50:50 | 只看该作者
太高深了,我先继续学习基本编程,等我能做出个正经程序来再说
回复  

使用道具 举报

17#
 楼主| 发表于 9-1-2009 15:30:47 | 只看该作者
今天看了自己第7章,这个,http://doc.trolltech.com/4.4/tutorials-tutorial-t7.html 自己定义widget这块,其他地方都比较好懂,但是不太明白为什么头文件中定了一signals

signals:
     void valueChanged(int newValue);

但是却找不到valueChanged这个函数的内容呢?高人帮我解答一下吧。还有个问题,signal的名字可以自己随便起吗?

更新:
我找了了解释,Signals are automatically implemented in the meta-object file. signal是自动实现的,这里我又有了疑问,既然是自动实现的,就肯定需要遵守一定的规则吧?比如命名、数据类型什么的,都有哪些规则呢?

还有,signal的使用,也不是很清楚,例子中
      connect(slider, SIGNAL(valueChanged(int)),
             lcd, SLOT(display(int)));
    connect(slider, SIGNAL(valueChanged(int)),
             this, SIGNAL(valueChanged(int)));
第一句中,什么地方把slider的新值传递给slot的呢?还是说这个connect函数本身就是其这个作用的,只要SIGNAL()和SLOT()这两个括号中的数据类型是一致的就可以配对使用呢?如果是这样,我是否可以控制SIGNAL送出的数据呢?比如在第二句中,当slider值改变这个信号来的时候,我让this发出一个比如时间或者别的信号,能不能这么做呢?

请高手解答以下,多谢,这里有点糊涂。

[ 本帖最后由 四香油饼 于 9-1-2009 16:51 编辑 ]
回复  

使用道具 举报

18#
发表于 9-1-2009 16:25:58 | 只看该作者
signal就是信号, 这个是qt里面类似消息转递机制
每一个Qt对象都有signals(发送消息)和slots(接收消息)。

connect(slider,                               SIGNAL(valueChanged(int)),    lcd,         SLOT(display(int)));
slider  这个是你的控件对象   
SIGNAL(valueChanged(int)) 这个是你控件对象触发信号, 看名字就是在slider值变化的时候会触发。
lcd,这个是你要触发对象
SLOT(...)就是你要做的触发对象的事情函数。

connect就是把slider的事件和lcd的事件联系起来了:
当slider的value改变了, 就会触发对象lcd的display函数, 2个int参数也传递。
回复  

使用道具 举报

19#
发表于 9-1-2009 16:37:26 | 只看该作者
原帖由 coredump 于 8-1-2009 18:22 发表

这不矛盾的, C++, Java, C#各有各的应用领域。

对于QT来说,学它的目的可以是:

1. 开发手机应用
    Nokia收购了QT,并且移植到了S60系统上,此外Trolltech原来就有个基于Linux的Qtopia嵌入式平台(现在叫Q ...


我还真不知道qt那么强大呢。  看来我也要好好学习qt了。
回复  

使用道具 举报

20#
 楼主| 发表于 9-1-2009 17:14:47 | 只看该作者

回复 #18 migao21 的帖子

但我如何知道传递的就是slider的值呢?如果我自己定义一个signal,又如何知道它传递什么值呢?
回复  

使用道具 举报

21#
发表于 9-1-2009 18:43:49 | 只看该作者
   
(1)  connect(slider, SIGNAL(valueChanged(int)), lcd, SLOT(display(int)));
(2)  connect(slider, SIGNAL(valueChanged(int)), this, SIGNAL(valueChanged(int)));
第一句中,什么地方把slider的新值传递给slot的呢?还是说这个connect函数本身就是其这个作用的,只要SIGNAL()和SLOT()这两个括号中的数据类型是一致的就可以配对使用呢?如果是这样,我是否可以控制SIGNAL送出的数据呢?比如在第二句中,当slider值改变这个信号来的时候,我让this发出一个比如时间或者别的信号,能不能这么做呢?

(1)中, slider的valueChanged的时候就会把int值传给slot display函数

假设一个下拉框在mainwindow里面,同时还有一个文本行,定义如下:
QComboBox *QCB_abc;
QTextEdit *QTE_abc;

下拉框QComboBox控件有以下signal函数,可以直接调用
void QComboBox::currentIndexChanged ( const QString & text )   [signal]

你在mainwindow里面定义slot函数display(const QString & text )
void mainwindow::display(const QString & text )
{
    QTE_abc->setText (text ); // show the text of combo box to mainwindow
}

在mainwindow的构造函数里面, 有以下语句:
// 实例化QCB_abc
// 添加下拉框QCB_abc里面的内容
// 实例化QTE_abc

connect(QCB_abc, SIGNAL(currentIndexChanged (const QString & text )), this, SLOT(display()));
....

在运行以后,出现mainwindow,里面有个下拉框和文本框, 当你改变下拉框的值得时候, 改变的值会出现在文本框里面。

(2) 你不可以将一个signal传给另外一个signal, 信号只是信号, 并不触发任何事件, 你需要调用slot函数来触发事件。

不同控件有哪些signal可以直接用,或者有哪些现成的slot函数可以直接调用,你可以直接查qt帮助文档。
回复  

使用道具 举报

22#
发表于 9-1-2009 21:11:30 | 只看该作者

回复 #17 四香油饼 的帖子

先看看QT文档的信号槽机制原理相关的章节,这是QT最核心的特性之一,必须完全理解才能继续:
http://doc.trolltech.com/4.4/signalsandslots.html
回复  

使用道具 举报

23#
发表于 9-1-2009 21:29:40 | 只看该作者
等找到工作后有时间学C++的时候就跟着搂主混了。
回复  

使用道具 举报

24#
发表于 9-1-2009 21:33:10 | 只看该作者
油饼我觉得你有时间不如学学C#的编程,可比QT有用多了,玩玩visual studio。
回复  

使用道具 举报

25#
发表于 9-1-2009 23:03:36 | 只看该作者
建议LZ同时学 C#, C++, Java, Objective-C 正好四箱油饼
回复  

使用道具 举报

26#
发表于 9-1-2009 23:27:18 | 只看该作者
how about D language
回复  

使用道具 举报

27#
 楼主| 发表于 9-1-2009 23:44:52 | 只看该作者
原帖由 migao21 于 9-1-2009 19:43 发表

(1)中, slider的valueChanged的时候就会把int值传给slot display函数

假设一个下拉框在mainwindow里面,同时还有一个文本行,定义如下:
QComboBox *QCB_abc;
QTextEdit *QTE_abc;

下拉框QComboBox控件有 ...


谢谢migao, signal传给signal,是那个例子里的阿,所以我糊涂呢,你看 http://doc.trolltech.com/4.4/tut ... 7-lcdrange-cpp.html
回复  

使用道具 举报

28#
 楼主| 发表于 9-1-2009 23:47:49 | 只看该作者
原帖由 coredump 于 9-1-2009 22:11 发表
先看看QT文档的信号槽机制原理相关的章节,这是QT最核心的特性之一,必须完全理解才能继续:
http://doc.trolltech.com/4.4/signalsandslots.html


我听你的,先去看这个吧,搞清楚了再往下看
回复  

使用道具 举报

29#
发表于 10-1-2009 11:17:02 | 只看该作者

回复 #26 tkl888 的帖子

D设计上很不错,致力于C++的改良。不过貌似社区很不活跃,纯粹用着学来玩还是很有趣的。很多特性真的让人眼前一亮
回复  

使用道具 举报

30#
 楼主| 发表于 12-1-2009 20:54:48 | 只看该作者
今天学习了一些有关singal/slot的进一步的知识,现在根据自己的理解做个总结:

1. 自定义类如果需要使用signal/slot,必须在类中最开始加上 Q_OBJECT 说明
2。signal函数不用自己实现,只需要写出定义就行了,前面加上signals:关键字
signals:
    void ValueChanged(int value);
3. signal的使用,在需要发出singal的地方,用emit关键字,
  emit ValueChanged(xxxx);
4.signal/slot 可以有任意多个任意类型的参数,而且可以想连接的2个参数数量可以不一致。(这个请专家指导一下,比如signal发出2个参数,第一个是int 第二个是 char*,slot只有一个char*,能配对吗?)
5。slot像调用函数,connect语句后面的程序只有等slot执行完成后,才会继续执行(除非使用queueed connections)
6。signal/slot需要使用翻译成标准的c++才能编译,可以通过qmake实现,具体细节我先不细看了。
7。当一个slot同时接受多个signal时,可以由QSignalMapper来区分signal来源,我先跳过细节,用到再看。

评分

参与人数 1威望 +30 收起 理由
coredump + 30 学习能力很强,赞!

查看全部评分

回复  

使用道具 举报

您需要登录后才可以回帖 登录 | FreeOZ用户注册

本版积分规则

小黑屋|手机版|Archiver|FreeOZ论坛

GMT+10, 2-9-2025 15:34 , Processed in 0.065696 second(s), 47 queries , Gzip On, Redis On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表