qt信号槽之创建和连接自定义的槽

在第一版的Qt设计器中,你可以创建你自定义的槽的信号并使他们连接起来,但是你不能直接实现你的槽,你不得不子集于该窗体,并在这个子集中对你自定义的槽编码,子集的方法依然有用,在某些情况下仍起作用(Make sense),但是现在你可以在Qt设计器中直接实现你的槽,在多的对话框和窗体的子集也不再需要了。(Qt设计器在.ui.h文件中存贮者槽的实现,具体的细节参看 走近设计器(The Designer Approach)中的.ui.h扩展方法)。

  多项剪辑应用程序需要四个槽,一个用于每个按钮,因为我们将一个信号连接到预定义的槽使得按下退出按钮时退出程序,所以仅有三个槽需要我们自定义,我们需要我增加剪辑按钮实现一个槽,其作用是将当前剪辑添加到列表框中,复制以前的按钮(Copy Previous)需要一个槽实现复制列表框中选中的项到线型编辑框中(也复制到剪贴板上),删除剪辑按钮(Delete Clipping)需要一个槽实现删除党旗那剪辑和列表框中的当前项,我们也需要写一些初始化的代码使得程序启动时,将当前剪贴板上的文本(如果有的话)复制到线型编辑框中,代码可以直接在Qt设计器中编写,声称的已写好的代码片断可以下面的文件中获取:qt/tools/designer/examples/multiclip/multiclip.ui.h

  我们需要一个Qt的全局剪贴板对象,在整个代码中有几个地方需要调用其含义是调用QApplication::clipboard()或者是qApp->clipboard(),比执行这些函数调用更好的方法,我们在窗体本身添加一个指向剪贴板的指针,点击对象浏览器中的源码标签(如果对象浏览器部可见,点击 Windows|Views|Object Explorer [由于Qt设计器没有汉化,再说汉化后似乎失去了其魅力,所以菜单的引用依然是English])源码标签显示了当前窗体中的函数、类变量、前部的声明和我们需要的一些包含文件的名字。

   鼠标右键点击类变量(Class Variable)项(可能在底部,你需要点击滑动条),然后再弹出的菜单中选择New子菜单,(如果存在变量,则弹出来的菜单中会有一个“Delete”删除的选项)键入QClipboard * cb 并按下Enter键确认输入,我们将创建一个init()函数,在这个函数中我们会赋予这个指针一个Qt的全局剪贴板对象的值。我们也需要声明剪贴板对象的头文件,右键点击包含(声明文件)[在Qt设计器中对应的为 Include(in Declaration)项],然后再弹出的菜单上选择 New ,键入“”,并按下Enter键确认输入,因为我们需要一个全局对象,qApp,我们就必须包含另一个声明文件,鼠标右键点击 包含(实现)项[在Qt设计器中对应为Include (in Implementation)],然后点击New 菜单项,键入“”并按下Enter键确认输入,这个变量和声明文件将被Qt设计器的.ui文件生成后包含(丛.ui文件生成的源文件.h 和.cpp文件会包含这个变量和声明文件)。

We will invoke Qt Designer's code editor and write the code.  现在我们将激活Qt设计器的代码编辑器并编写代码。

  首先我们创建一个init()函数,激活代码编辑器的一种途径是点击Source标签,然后点击你想编写代码的函数的名字,如果没有你需要的函数或者你想创建一个在Source标签中你可用的新函数,鼠标右键点击Source标签的槽(Slots)列表中的“protected”子项,然后点击New子菜单,出现一个“Edit Slots”编辑槽的对话框,改变槽的名字为Init(),然后点击OK,这样你可以点击编辑窗口中出现的函数名字并键入你的代码。

   注意到并不是强迫你使用Qt设计器的代码编辑器,在Qt设计器中你可以尽管的增加、删除或者重命名你的槽,你也可以用一个外部的编辑器编写的实现代码,Qt设计器会保存你所写的代码。下面是你需要实现的init()函数:

    void MulticlipForm::init()
    {
        lengthLCDNumber->setBackgroundColor( darkBlue );
        currentLineEdit->setFocus();

 

        cb = qApp->clipboard();
        connect( cb, SIGNAL( dataChanged() ), SLOT( dataChanged() ) );
        if ( cb->supportsSelection() )
            connect( cb, SIGNAL( selectionChanged() ), SLOT( selectionChanged() ) );

 

        dataChanged();
    }

函数体中开始的两行改变了数字指示器的背景颜色并使窗体的启动焦点在线型编辑框中,我们使用了一个指向Qt全局剪贴板的指针,并保存在我们定义的类变量 cb 中,我们连接剪贴板的dataChanged()信号到一个叫做 dataChanged()的槽,这个操我们马上就会创建,如果剪贴板支持选择(例如在X Windows系统中),我们也要连接剪贴板的selectionChanged()信号到一个我们将创建的具有相同名字的槽,最后我们将调用我们的dataChanged()槽函数,当程序启动时,将当前剪贴板中的文本内容(如果有的话)粘贴但线型编辑框中

 既然我们提到了dataChanged()和selectionChanged()槽,下面我们将对他们编码,从dataChanged()开始:

    void MulticlipForm::dataChanged()
    {
        QString text;
        text = cb->text();
        clippingChanged( text );
        if ( autoCheckBox->isChecked() )
            addClipping();
    }

  我们复制了剪贴板的文本并用我们获得文本调用我们自己定义的clippingChanged()槽,如果用户选中了自动增加剪辑检测框,我们将调用addClipping()槽增加该剪辑到列表框中。

 下面的代码只是在X Windows系统中可用,微软的Windows用户也能包含下面的代码确保该应用程序可以在多平台下运行。

    void MulticlipForm::selectionChanged()
    {
        cb->setSelectionMode( TRUE );
        dataChanged();
        cb->setSelectionMode( FALSE );
    }

 上面的代码中我们首先告诉剪贴板使用选择模式 ,我们调用dataChanged()槽获得任何选中的文本,然后设置剪贴板为默认模式。

In the another custom slot, clippingChanged().在另一个自定义的槽中,clippingChanged():

    void MulticlipForm::clippingChanged( const QString & clipping )
    {
        currentLineEdit->setText( clipping );
        lengthLCDNumber->display( (int)clipping.length() );
    }

  我们用任何传递给clippingChanged()槽的文本设置当前的线型编辑框,并用这个新文本的长度更新数字指示器。

   我们将要编码实现的下一个槽实现增加剪辑功能,当用户点击增加剪辑按钮时,这个槽被我们的代码内部调用(看上面的dataChanged()槽),即使我们让Qt设计器能够通过在编辑窗口键入代码来创建一个槽与信号的连接,我们也让Qt设计器为我们创建一个结构,(为我们生成程序框架),点击Edit|Slots 激活编辑槽(Edit Slots)对话框,点击New Slot按钮并把槽的缺省名字“new_slot()”改为“addClipping()”,这里不必改变访问标着和返回类型,现在我们已经创建了我们的槽,我们能在代码编辑器中出现的地方创建我们的槽并实现之。

增加剪辑按钮用于从当前剪辑线型编辑框中复制文本到列表框中,同时我们更新了文本长度数字指示器。

    void MulticlipForm::addClipping()
    {
        QString text = currentLineEdit->text();
        if ( ! text.isEmpty() ) {
            lengthLCDNumber->display( (int)text.length() );
            int i = 0;
            for ( ; i < (int)clippingsListBox->count(); i++ ) {
                if ( clippingsListBox->text( i ) == text ) {
                    i = -1; // Do not add duplicates
                    break;
                }
            }
            if ( i != -1 )
                clippingsListBox->insertItem( text, 0 );
        }
    }

  如果有新文本需要显示,同时改变数字指示器的值为当前文本的长度,然后我们在列表框中逐个比较文本项,看当前输入的文本是否存在列表框中,如果列表框中不存在该剪辑文本项,就在列表中插入该剪辑文本。

 为了使增加剪辑按钮工作,我们需要连接这个按钮的addClipping()槽,点击 Connect Signal/Slots 工具栏按钮,然后点击增加剪辑按钮,(将变成十字型的鼠标拖动到窗体上点击该按钮然后释放),(确认你拖向窗体而不是其他部件—拖动过程中窗体会有一个细红色边界,如果你操作错误你只需在槽组合框中改变其名字就可以了[这里我按原文翻译,可是有些地方和单词觉得上下文不对,如果你发现了正确的请与我联系])。连接编辑对话框将会显示,点击addClipping()槽,点击OK按钮确认该连接。

  复制前一个文本按钮(Copy Previous)用于从列表框中复制选中的文本项到线型编辑框中,同时该文本也放到了剪贴板上,剩下来的过程和增加剪辑按钮(Add Clipping)是一样的:首先我们创建一个槽,然后我们实现该槽,最后我们将按钮点击的信号和槽连接起来。

1.    创建槽:

 点击Edit|Slots菜单子项,激活槽编辑(Edit Slots)对话框,点击 New Slots 并将缺省的槽函数名字“new_slot()”改变为“copyPrevious()”,点击OK确认。

2.    实现槽函数

3.               void MulticlipForm::copyPrevious()
4.               {
5.                   if ( clippingsListBox->currentItem() != -1 ) {
6.                       cb->setText( clippingsListBox->currentText() );
7.                       if ( cb->supportsSelection() ) {
8.                           cb->setSelectionMode( TRUE );
9.                           cb->setText( clippingsListBox->currentText() );
10.                       cb->setSelectionMode( FALSE );
11.                   }
12.               }
13.           }

    这段复制上次剪辑的代码检测列表框中是否有选项选中,如果有选项被选中则该项会被复制到线型编辑框中,如果我们使用了一个支持选择的系统,我们将不得不重复复制,复制的次数和选择模式有关,我们不要显示的更新剪贴板,当线型编辑框的文本改变时,他发射了一个dataChanged()的信号,这个信号被我们创建的dataChanged()槽接收,我们的这个dataChanged()槽同时更新剪贴板。

14.连接到槽

 点击 Connect Signal/Slots 工具栏按钮,点击复制上次剪辑(Copy Previous)按钮,拖动到窗体然后释放鼠标,(光标变成十字型后,点击某个部件1,如按钮,拖动鼠标到另一个部件2或者窗体,则在出现的信号槽连接编辑对话框中,信号的发射者是部件1,接受信号的槽是部件2或者窗体的[试试就知道了J]),在弹出的连接编辑对话框中,点击clicked()信号和copyPrevious()槽,点击OK确认连接编辑。

  用同样的方法我们对删除剪辑(Delete Clipping)按钮进行信号和槽的连接编辑。

1.    点击Edit|Slots 菜单激活槽编辑对话框,点击 New Slot 按钮并替换缺省的槽名字为“deleteClipping()”,点击OK按钮。

2.    删除按钮必须删除列表框中的当前项并清除线型编辑框中的文本。

3.               void MulticlipForm::deleteClipping()
4.               {
5.                   clippingChanged( "" );
6.                   clippingsListBox->removeItem( clippingsListBox->currentItem() );
7.               }

我们以一个空字符串调用我们自己创建的clippingChanged()槽,使用列表框的removeItem()函数删除当前选项。

8.    连接删除剪辑(Delete Clipping )按钮的clicked()信号到我们创建的deleteClipping()槽,(按下F3键---这个点击Connnect Signals/Slots工具栏按钮效果一样,点击删除剪辑按钮并拖动鼠标到窗体上,释放鼠标,出现连接编辑对话框,点击clicked()信号和deleteClipping()槽,点击OK()确认连接编辑)

编译和生成应用程序

至此在Qt设计器中,我们写了一个Qt整个应用程序大约99%的代码,为了使应用程序编译和运行我们必须创建一个main.cpp文件,在这个文件中我们将显示调用我们的窗体。

  创建一个新的源文件的简单方法是点击File|New激活“New File”新文件对话框,适当的点击“C++ Source”或者“C++ Header”图标,然后点击“OK”按钮确认,一个新的空源文件显示出来,点击File|Save 激活另存为对话框(Save As ),键入“main.cpp”然后点击Save按钮保存该文件。

在main.cpp这个C++编辑窗口,键入以下代码。

    #include <qapplication.h>
    #include "multiclip.h"

 

    int main( int argc, char *argv[] )
    {
        QApplication app( argc, argv );

 

        MulticlipForm clippingForm;
        app.setMainWidget( &clippingForm );
        clippingForm.show();

 

        return app.exec();
    }

  这个程序创建了一个QApplication对象和我们的多项剪辑窗体的实例,并将该窗体设置为主部件并显示该窗体,app.exec()开始调用程序事件循环。

 现在启动控制台命令(命令行格式),并将当前目录切换到multiclip程序下,运行qmake命令,一个与你的系统兼容的Makefile文件将会生成。

qmake -o Makefile multiclip.pro

   现在你可以通过运行make或者nmake命令生成该应用程序。试着编译和运行Multiclip,你会取得许多的进步,使用布局工具和编写代码的试验可以帮助你学到关于Qt和Qt设计器的更多的东西。

  这一章向你介绍了使用Qt设计器创建一个跨平台的应用程序,我们创建了一个窗体并且用部件对其修饰,这些部件整齐优美的放置在窗体上并可以随着窗体缩放,我们已经使用了Qt的信号和槽的机制实现程序的功能,并生成了Makefile文件,这些增加部件到窗体并用布局工具对其放置,以及创建、编写和连接槽的技术,当你再次用Qt设计器创建程序是会用到,下面的章节会给出进一步的例子并介绍使用Qt设计器的更多技术。

翻译者 volrender

E-mail  volrender@163.com 


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值