|
1, Signal和Slot。
简单地说就是信号和信号接受器,他跟callback方式的回调函数实现不一样。简单的例子:点击一个按钮,就会触发他的clicked()这个signal,另外有一个dialog,他有一个show()的slot,signal和slot都不关心自己将跟谁连接或者被谁连接。但是一个基本原则就是类型安全,参数要一致(slot的参数可以少于signal,因为它可以丢弃参数),比如如果你希望点击按钮打开对话框的话:
QPushButton *btn = new QPushButton(“打开对话框”);
QDialog *dlg=new QDialog();
connect(btn, SIGNAL(clicked()), dlg, SLOT(show()));
在举一个包含参数的例子:
QLCDNumber *lcd = new QLCDNumber();
QSlider *sl = new QSlider(Qt::horizontal);
sl->setRange(0,99);
sl->setValue(0);
connect(sl, SIGNAL(valueChanged(int)), lcd, SLOT(display(int)));
2, Q_OBJECT
这个宏在QT/KDE编程中很常见,到底是什么意思你也没有必要理会
在QT编程中,如果是自己实现的控件,比如从QVBox,QWidget,QMainWindow之类的继承而来的类,如果有自己的signal和slot实现,就要在类声明的最前面,加入Q_OBJECT这个宏,如果没有新的signal/slot定义,就不需要了。也就是如果类中存在signals: public slots:的定义就要加入这个宏。
在KDE编程中,都要加入Q_OBJECT这个宏。
3, Moc(Meta Object System)
Moc其实就是对signal/slot机制的实现。
如果一个类声明含有了Q_OBJECT宏,他就会对这个类声明进行moc,生成一个新的C代码文件,习惯定义后缀名为moc,要包含进类实现的文件,比如在Cpp文件最后加上#include “abc.moc”或者跟类实现链接。
在Qt/KDE编程中,自己定义的signal是不需要进行实现的,只有slot需要进行实现。Singal的实现工作由moc完成。
4, Designer和UI
Qt提供了两个工具,可以方便开发者在开发过程中使用:assistant和designer,assistant是文档中心,所有的qt类文档都可以找得到,上百个类,背不下来的,所以开发时肯定要参考文档。
Designer的功能也很容易理解,用来可视化的画UI的。但是,画出来UI之后怎么加入到你的工程呢?
其实很简单:
启动designer之后,你可以选择画widget/mainwindow/dialog/wizard等各种类型,随便画一种,生成一个UI文件,然后使用uic对他进行处理。
uic abc.ui >abc.h
uic –impl abc.h abc.ui >abc.cpp
这时候你就得到了你要构建的UI的头文件和类实现,如果是简单的任务,就可以直接加入工程了。就想自己构架的组件一样的使用。
通过designer也可以定义slot,signal什么的,建议,生成source后实现。
如果使用kdevelop,可以使用工具自动实现UI到source的转换。
5, Qmake:
一个qt程序,怎么才能最方便的编译,难道moc, 编译联结之类的行为都要自己手动写?
qmake –project 生成一个目录名.pro工程文件
qmake 从目录名的pro生成makefile
make 编译生成“目录名”的可执行程序
就可以了
6, DCOP
这个是KDE独有的东西。
Dcop就是桌面通讯协议的意思。是一个类CORBA协议,但是非常简单。
设计dcop的目的就是需要在程序之间进行通讯,举个例子:一个应用程序发送一个消息给panel,说“我已经启动,不要显示“程序启动”的等待状态了”或者一个新应用程序询问是否有同名程序正在运行。如果是,调用并创建一个新的窗口,而不是启动一个新的进程。
DCOP有两种方法:send()和call(), send是异步的,只管发送,不管接受,send函数的返回值表示send行为成功与否,call比send多两个参数,返回值类型和返回值,他是同步拥塞的,必须等待返回值。
建立DCOP的方法很简单,消息发送端需要用到dcopClient(),attach(), registerAs(),QByteArray, QDataStream, send() and call();
首先:
DCOPClient *client=kapp->dcopClient();建立client对象
client->attach(); //跟服务器取得连结。
如果只是发送,不必进行registerAs()。这时候你不能获得appId也就必须进行匿名的连结了。
registerAs返回一个唯一标示符,可以进行身份辨识;假设外部程序有一个doIt函数,接受int型参数,那么我们请求这个函数执行的方法是:
QByteArray data;
QDataStream arg(data, IO_WriteOnly);
arg << 5;
if (!client->send("someAppId", "fooObject/barObject", "doIt(int)", data))
qDebug("there was some error using DCOP.");
使用QDataStream的目的是为了将数据序列化。上面的someAppId就是外部接受的那个
程序使用了registerAs取得的,对象的引用必须使用完全的层次结构。
以后我会接着写DCOP, KIO, KPART, XML_GUI等等的东西,同时对panel applet, systray, kpart, DCOP, kio, KAPP编程的范例进行一些分析。 |
|