《KDE2/Qt编程金典》第二章:创建并显示一个窗口——2.6 为一个信号定义slot

weixin_38096704 2019-09-19 05:15:56
为了让一个部件接收某个信号,它必须定义一个slot,并将此slot和某个信号相连接。下面的例子,显示了一个按钮和一个计数器,无论何时按下此按钮,计数器就加1,为了完成同样的工作需要做几件事情,不过Qt系统将会处理大部分的细节工作。特别需要指出的是,有一些特殊的宏和Meta对象编辑器(MOC, Meta Object Compiler)将自动处理大部分的细节工作。在这个例子中的main()函数很简单地创建并显示了此部件:1     /* count.cpp */2     #include <qapplication.h>3     #include "clickcount.h"4     5     int main(int argc, char **argv)6     {7         QApplication app(argc, argv);8         ClickCount clickcount;9         app.setMainWidget(&clickcount);10         clickcount.show();11         return(app.exec());12     }  ClickCount部件包含了一个按钮和一个标签。标签用来显示当前计数器的值:1     /* clickcount.h */2     #ifndef CLICKCOUNT_H3     #define CLICKCOUNT_H4     5     #include <qpushbutton.h>6     #include <qlabel.h>78     class ClickCount: public QWidget9     {10         Q_OBJECT11     public:12         ClickCount(QWidget *parent=0, const char *name=0);13     public slots:14         void incrementCounter();15     private:16         int counter;17         QLabel *label;18         QPushButton *button;19     };2021     #endif  在任何有slot的类中必须有第10行显示的宏Q_OBJECT(它也必须残存在于需要广播信号的类中,在第5章将学习到有关知识)。宏Q_OBJECT定义了一些标准方法,为了让信号和slot正常工作,它们必须存在于类中。  第14行中的incrementCounter()方法,在第13行中被设置为 public slot。除了定义为slot之外,incrementCounter()和类中的其它方法完全一样,它不仅可以被一个信号调用,而且也可以被直接调用。  ClickCount类的构造函数创建的布局包含了按钮和标签,指定了连接,实现从按钮发送信号到名为incrementCount的slot:1     /* clickcount.cpp */2     #include <stdio.h>3     #include "clickcount.h"4     5     ClickCount::ClickCount(QWidget *parent, const char *name):6               QWidget(parent, name)7     {8         setMinimumSize(120, 125);9         setMaximumSize(120, 125);1011         counter = 0;12         button = new QPushButton("Add 1", this);13         button->setGeometry(15, 15, 90, 40);14         label = new QLabel("0", this);15         label->setGeometry(15, 70, 90, 40);16         label->setAlignment(AlignVCenter | AlignHCenter);1718         QObject::connect(19               button, SIGNAL(clicked()),20               this, SLOT(incrementCounter()));21     }22     void ClickCount::incrementCounter()23     {24         char str[30];25         sprintf(str, "%d", ++counter);26         label->setText(str);27     }  在第8行和第9行调用了setMinimumSize()函数和setMaximumSize()函数,将窗口尺寸设置为120x125像素。在第11行进行计数器的初始化,第12到16行创建和配置了按钮和标签。  在第18行的调用QObject::connect()将一个slot连接到一个信号上。在第19行中,前两个参数指定了信号的来源是一个名叫clicked()的方法。clicked()信号是按钮类的一个成员,相应的还有其它信号,分别叫做pressed()、released()和toggled()。  在第20行中,QObject::connect()后两个参数指定了接收信号的对象和方法。对象使用的是this(指当前ClickCount的实例),方法是incrementCounter()。  每次clicked()信号被按钮发送出去的时候,它就被incrementCounter()方法所接收,此方法在所显示的值上加1,并且更新按钮的文本。  注意:在信号和slot中间并没有真实的连接。无论有无监控的slot,信号都将被广播,而且对于同一个信号,监控的slot的数目是任意的。此外,一个slot可以被设置成监控任意数目的信号。  这个例子的makefile文件说明了在Meta对象编译器(Meta Object Compiler)中如何将自己的输入作为定义类的头文件的代码,以便产生一个新的源文件用来编译以及和程序进行链接:1     INCL= -I$(QTDIR)/include -I$(KDEDIR)/include2     CFLAGS= -O2 -fno-strength-reduce3     LFLAGS= -L$(QTDIR)/lib -L$(KDEDIR)/include -L/usr/X11R6/lib4     LIBS= -lqt -lX11 -lXext5     CC=g++67     count: count.o clickcount.o moc_clickcount.o8         $(CC) $(LFLAGS) -o count count.o clickcount.o moc_clickcount.o $(LIBS)910     count.o: count.cpp clickcount.h1112     clickcount.o: clickcount.cpp clickcount.h13     moc_clickcount.cpp: clickcount.h14         $(QTDIR)/bin/moc clickcount.h -o moc_clickcount.cpp1516     clean:17         rm -f count18         rm -f count.o19         rm -f clickcount.o20         rm -f moc_*2122     .SUFFIXES: .cpp2324     .cpp.o:25         $(CC) -c $(CFLAGS) $(INCL) -o $@ $<  在第7行中显示程序不仅依赖于count.o和clickcount.o ,而且依赖于moc_clickcount.o。这个moc_clickcount.cpp是由MOC编译器从clickcount.h创建而来的。Q_OBJECT宏向ClickCount类定义中增加了一些方法原型,而MOC编译器产生这些新方法的实体。这样做的结果是,信号和slot所需要的重复性的编码工作(这样的工作很容易产生错误)几乎全部自动完成了。
...全文
18 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复

433

社区成员

发帖
与我相关
我的任务
社区描述
其他技术讨论专区
其他 技术论坛(原bbs)
社区管理员
  • 其他技术讨论专区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧