Qt学习之路_3(VS下Qt的信号与槽初次体验)

来源:互联网 发布:周传雄 黄昏 知乎 编辑:程序博客网 时间:2024/06/10 10:17

Qt学习之路_3(VS下Qt的信号与槽初次体验)

  在Qt中是使用信号与槽的机制来完成事件的响应过程的。网上Qt的开发基于Qt Creator的资料比较多,基于vs下的资料除了其环境配置方面的外就剩下很少了。开始以为2者环境下的开发方式相同,后面稍微接触了下发现还是有微妙的区别的,Qt在vs下毕竟是add-in嵌入的,用起来不如Creator中方便,比如对某控件而已不能自动go to slot,所以一些固定格式的代码需要自己手动添加,幸运的是,2者下的开发大致相同。

  本文按官网上一篇英文资料操作了一遍,初步体验了Qt中的信号与槽的机制,网址为:

      http://doc.qt.nokia.com/vs-add-in-1.1.7/vs-addin-getting-started.html#designing-the-main-dialog

  程序实现的功能是:添加和删除用户的姓名和其email地址。其有2个界面,分别为1个主窗口界面和一个对话添加用户名和email窗口界面。

  按照网页教程分别完成下面步骤:

  1. 新建一个Qt应用程序框架
  2. 用Qt设计师设计主窗口(其实也是一个对话框窗口),主窗口包括1个QListWidget,2个PushButton,2个QLabel。
  3. 设计一个”添加用户地址”对话框界面,包括2个QLabel,2个QLinEdit,1个QPushButton。
  4. 为”添加用户地址”界面的OK按钮增加信号与槽的联系。此时可以在UI设计师的编辑\信号槽模式下进行,具体方法是拖动OK按钮释放后选择对应的信号与槽,见网页详细介绍。
  5. 实现主窗口中Add按钮的显示”添加用户地址”界面,并且响应该界面中的用户名输入和ok按钮。这一部分要特别注意,除了实现功能代码外,还需自己手动添加一些其他的代码(Qt Creator可以自动添加,vs下找了很久没有发现)。我们需要在3个地方添加代码,第1个是在addressbook.h文件下添加一个槽函数声明,即属于private slots类型,添加后如下所示:

      

   第2个添加地方为在addressbook.cpp中添加adddialog.h头文件。

     最后一个地方为addressbook.cpp实现add按钮功能,其代码为(为什么cnblog的代码折叠功能不能用呢?):  

void AddressBook::on_addButton_clicked(){    AddDialog dialog(this);    if (dialog.exec()) {    //等待用户的输入,为模态对话框,对话框以外的操作不响应        QString name = dialog.nameEdit->text();        QString email = dialog.emailEdit->text();        if (!name.isEmpty() && !email.isEmpty()) {//当2者输入都非空时            QListWidgetItem *item = new QListWidgetItem(name, ui.addressList);//用于在QListWidge中显示的条目            item->setData(Qt::UserRole, email);//UserRole指的是后面的数据类型是针对特定程序应用的            ui.addressList->setCurrentItem(item);//把item放入QListWidge中        }    }}

  6. 用同样的方法完成主窗口中显示选中的Item的功能

  7. 用同样的方法完成”添加用户地址”界面的delete按钮功能。

  下面为几个主要文件的整体代码:

  adddialog.h:

#ifndef ADDDIALOG_H#define ADDDIALOG_H#include <QDialog>#include "ui_adddialog.h"class AddDialog : public QDialog, public Ui::AddDialog{    Q_OBJECTpublic:    AddDialog(QWidget *parent = 0);    ~AddDialog();};#endif // ADDDIALOG_H

  addressbook.h:

#ifndef ADDRESSBOOK_H#define ADDRESSBOOK_H#include <QtGui/QMainWindow>#include "ui_addressbook.h"class AddressBook : public QMainWindow{    Q_OBJECTpublic:    AddressBook(QWidget *parent = 0, Qt::WFlags flags = 0);    ~AddressBook();private:    Ui::AddressBookClass ui;private slots:    void on_addButton_clicked();//即使是系统能识别的命名方式,该语句还是不能少    void on_addressList_currentItemChanged();    void on_deleteButton_clicked();};#endif // ADDRESSBOOK_H

  adddialog.cpp:

#include "adddialog.h"AddDialog::AddDialog(QWidget *parent)    : QDialog(parent){    setupUi(this);}AddDialog::~AddDialog(){}

  addressbook.cpp:

#include "addressbook.h"#include "adddialog.h"AddressBook::AddressBook(QWidget *parent, Qt::WFlags flags)    : QMainWindow(parent, flags){    ui.setupUi(this);//    connect( ui.addButton, SIGNAL(clicked()), this, SLOT(onaddButton_clicked()) );//如果是系统能识别的名字的话,这条语句可以省略//    connect( ui.deleteButton, SIGNAL(clicked()), this, SLOT(on_deleteButton_clicked()) );}AddressBook::~AddressBook(){}void AddressBook::on_addButton_clicked(){    AddDialog dialog(this);    if (dialog.exec()) {    //等待用户的输入,为模态对话框,对话框以外的操作不响应        QString name = dialog.nameEdit->text();        QString email = dialog.emailEdit->text();        if (!name.isEmpty() && !email.isEmpty()) {//当2者输入都非空时            QListWidgetItem *item = new QListWidgetItem(name, ui.addressList);//用于在QListWidge中显示的条目            item->setData(Qt::UserRole, email);//UserRole指的是后面的数据类型是针对特定程序应用的            ui.addressList->setCurrentItem(item);//把item放入QListWidge中        }    }}void AddressBook::on_addressList_currentItemChanged(){    QListWidgetItem *curItem = ui.addressList->currentItem();//获取当前item    if (curItem) {        ui.nameLabel->setText("Name: " + curItem->text());//curItem->text()指的是item最前面的那个标题        ui.emailLabel->setText("Email: " +            curItem->data(Qt::UserRole).toString());//item的内容,且转化成了String类型    } else {        ui.nameLabel->setText("<No item selected>");        ui.emailLabel->clear();    }}void AddressBook::on_deleteButton_clicked(){    QListWidgetItem *curItem = ui.addressList->currentItem();    if (curItem) {        int row = ui.addressList->row(curItem);//返回当前item所在的行数        ui.addressList->takeItem(row);//takeItem(row)表示移除掉当前row的item,并返回当前的item        delete curItem;        if (ui.addressList->count() > 0)//计算当前所有的item个数,包括隐含的item            ui.addressList->setCurrentRow(0);//显示第一个item        else            on_addressList_currentItemChanged();//其目的窗口是下面的edit内容不显示    }}

  main.cpp:

#include "addressbook.h"#include <QtGui/QApplication>int main(int argc, char *argv[]){    QApplication a(argc, argv);    AddressBook w;//直接相关的类就是addressbook,其它的比如addialog类只是设计其界面,功能的实现是间接实现的,无需更改其cpp文件    w.show();    return a.exec();}

 

本次试验的主要总结有下面2点:

  1. 在Ut设计师界面下,且运行于编辑\信号槽模式,如果使用图标连接了信号与槽之间的关系的话,则在此类中的构造函数中不需要实现connect()函数连接信号与槽了。
  2. 如果槽函数是采用系统能识别的默认函数名。比如Add按钮对于系统默认的函数名on_addButton_clicked(),则此时连设计界面的连接线等都不需要填了,直接可以在cpp程序中代码实现自己的功能即可。

 

 

 

作者:tornadomeet 出处:http://www.cnblogs.com/tornadomeet 欢迎转载或分享,但请务必声明文章出处。
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 小孩子头撞了头发长不出来怎么办 小孩子头磕破了不长头发怎么办 晚上洗了冷水头早上头痛怎么办 头发洗了一天就油了怎么办 米诺地尔搽剂喷了头皮油怎么办 头发可以种植吗如果是秃顶怎么办 前额头发少怎么办如何使头发增多 头发又细又软又少怎么办 宝宝一岁了头发又少又黄怎么办 生完孩子头发掉的厉害怎么办 洗完头发后头发很蓬松怎么办 头发掉的厉害怎么办吃什么好得快 头发掉的很厉害怎么办吃什么好 我头发掉的厉害怎么办吃什么药 头发干枯毛躁掉发怎么办吃什么 最近洗头时头发掉的厉害怎么办 生完小孩头发掉的厉害怎么办 生完小孩后头发掉的厉害怎么办 生完孩子后严重掉头发怎么办 生过孩子后掉头发严重怎么办 孩孑16岁了高中没考上怎么办 小孩的嘴巴里有点点该怎么办 小孩从出生哭笑嘴巴有点歪怎么办 儿童耳朵受伤后嘴巴歪了怎么办 手机锁屏图案忘了怎么办求解锁 忘给仓鼠买吃的了怎么办 两岁宝宝不爱吃饭只喝奶粉怎么办 下载百度云压缩包要提取密码怎么办 微信表情包图片过大无法添加怎么办 管理员吧群员全部踢了群主怎么办 微信笑脸表情斗图文字没有了怎么办 钨珠钢笔头用完笔墨了怎么办 暴走大事件被禁六一红鼻子节怎么办 弯腰推东西把腰闪了怎么办 怀孕初期弯腰捡东西腰不舒服怎么办 突然弯腰捡东西腰闪了怎么办 跑步机上的磁铁掉了怎么办 微信解封辅助申诉信息不一致怎么办 穿越火线进游戏字体变小了怎么办 微信登录显示版本过低登不上怎么办 手机显示主题版本过低不能用怎么办