Qt4学习笔记 (1)

This is a repost from my previous Qt learning series, based on Qt 4.3.

    为什么要学这个? 主要是学习其中的design pattern.
    丸子买不起书, 所以看的是电子版: C++ GUI Programming with Qt4, 2nd Edition

    作为一个跨平台的GUI库, 首先Qt用的design pattern是facade模式: 不管subsystem如何, 对外提供简单统一接口.
    跟wxWidgets一样, 每次你new出来的widget其实都是不用自己来delete的, Qt会自己帮你delete掉. 可以参看源码: /src/gui/kernel/qwidgets.cpp 中的析构函数. 注意如果你用MFC的话, memory是要你自己搞定的.
先来看一段最简单的Qt代码:

    诶.. 你发现既然是GUI的程序, 为什么用的入口函数是main(), 而不是WinMain()? 能看出这个问题你已经有相当的水平了. 其实Qt自己写了一个WinMain(), 在里面调用你的main(). 源码在这里可以找到: /src/winmain/qtmain_win.cpp (windows版本).
接下来再看一个稍微复杂一点的:

    于是你看到了Qt的事件处理机制signal/slot (信号? 插槽? 好x啊–b). 一个signal相当于一个event, slot相当于一个handler. signal和slot可以是多对多的关系. 其实这里包含了两个dessign pattern. observer模式显而易见, 还有一个就是mediator模式. 这样说应该懂了吧, 不懂的话请翻阅我之前写的design pattern系列的文章.
    另外, 可以参考Qt的官方文档: Signals and Slots. 上面大概说了这么几点重要的:
a) signals/slots/emit实际上都是macro(可以看源码). 对于c++ compiler来说, signals–>protected, slots–>nothing, emit–>nothing, 对于moc(这个工具下面会说)来说, 则被另外不同的preprosessor机制预处理.
b) 通过signal/slot可以调用private的slot(这个我没试过..不太好吧).
c) SIGNAL/SLOT宏, 这2个东西很搞, 实际上就是在函数名前加上”1″或者”2″结成新的字符串–b. 所以, 丸子觉得, 这里可能是不安全的, 如果拼错了的话编译器也是检查不出来的.
d) Q_SIGNALS/Q_SLOTS/Q_EMIT宏有特殊意义, 用于第三方的signal/slot机制避免冲突.
e) signal/slot的函数signature必须: *) 相同. *) 或者slot的参数比signal要少.
    最后, 你看到一个QButton自己show()就可以了. 没错, 因为QButton继承QWidget, QWidget都是可以直接show()的, 这点跟其他的GUI Kit不一样.
    这里有2个工具: moc(Meta-Object Compiler), uic(User Interface Compiler).
    moc用来维护Qt中类的运行时信息, 把它想象成Java中的reflection就可以了. 那么麻烦主要是由于C++本身不支持这个. 所以, 实际上signal/slot机制的实现也用到了这些信息, 因此一个Qt类一定要实现某些特定的接口函数, 这就是moc所做的工作了.
    uic用来把*.ui文件转化成C++代码, 以便能编译到一个binary中去. 用xml做ui真的是一个很不错的想法, 不过这里有一个问题啊. 那就是用uic生成C++代码之前, 其它C++类如果要引用ui中的成员变量似乎是不可能的. 诶.. 这个不知道怎么解决.

    つつく.

Leave a Reply

Your email address will not be published.