关闭

QT(5)Dialog - Addressbook例子3

标签: dialogqtfilesignalstringmakefile
3405人阅读 评论(0) 收藏 举报
分类:

  我们丰富Addressbook的例子,增加一个Find按键,可弹出一个dialog,参考:http://doc.qt.nokia.com/latest/tutorials-addressbook-part5.htmlhttp://doc.qt.nokia.com/latest/tutorials-addressbook-part6.htmlhttp://doc.qt.nokia.com/latest/tutorials-addressbook-part7.html,学习下面的内容:

  1. QDialog的使用方法。
  2. QFileDialog的使用方法
  3. 二进制和文本的文件读写
  4. split,QRegExp,QStringList等相关String的使用方法

  为此,我们增加FindDialg的类,继承QDialog。下图是主Window的界面,以及FindDialog的弹出界面。

  我们增加一个头文件finddialog.h和源文件finddialog.cpp来处理弹框。请注意在*.pro文件中加入相关的文件,通过qmake重新生成Makefile。finddialog.h如下:

按Find按钮后弹框:

#ifndef WEI_FINDDIALOG_H
#define WEI_FINDDIALOG_H

#include <QDialog>

class QLineEdit;
class QPushButton;

class FindDialog : public QDialog
{
    Q_OBJECT

public :
    FindDialog(QWidget * parent = NULL);
    QString getFindText();

public slots:
    void findClicked();

private:
    QPushButton * findButton;
    QLineEdit   * lineEdit;
    QString       findText;
};

#endif

  我们看看finddialog.cpp文件:

#include <QtGui>
#include "finddialog.h"

FindDialog::FindDialog(QWidget *parent): QDialog(parent)
{
    QLabel * findLabel = new QLabel(tr("Enter contact's name: "));
    lineEdit = new QLineEdit;
    findButton = new QPushButton(tr("&Find"));
    findText = "";

    QHBoxLayout * layout = new QHBoxLayout;
    layout->addWidget(findLabel);
    layout->addWidget(lineEdit);
    layout->addWidget(findButton);

    setLayout(layout);
    setWindowTitle(tr("Find Contact"));

    /* 我们在这里作两个test case。方式一:将findButton的clicked()信号连接两个slot函数,先是findClicked()然后是accept()。accept()是QDialog的一个函数,当QDialog hide的时候给出dialog的返回数值QDialog::Accepted。当我们处理了findClicked后,则依次调用accept(),这是dialog将会hide(注意在QT中不是关闭),并且返回一个resultcode:Accepted。这个处理关系如图所示 */
    connect(findButton, SIGNAL(clicked()), this, SLOT(findClicked()));
    connect(findButton, SIGNAL(clicked()), this, SLOT(accept())); //在Test case 2中我们注释此行。
}

void FindDialog::findClicked()
{
    QString text = lineEdit->text();
    if(text.isEmpty()){
        QMessageBox::information(this,tr("Empty Field"), tr("Please enter a name."));

        return; //在这个例子,如果是空的,执行完此,return后,调用accept,窗口会自行关闭
    }else{
        findText = text;
        lineEdit -> clear();

        //accept(); // Test Case2:由于处理findClicked后,没有下一步的accept,通过test2 我们可以比较了解信号依次出发的情况。
    }

}
/*在这里,我们注意到,宁可增加一个public来读取属性, 也不将该属性设置为public,即使目前只提供读的功能,这是一种好的编写风*/
QString FindDialog :: getFindText()
{
    return findText;
}

  现在补充addressbook.h,如下:

... ...
#include "finddialog.h"
... ...
class AddressBook : public QWidget
{
    ... ...
public slots:
    ... ...
    void findContact();

private:
... ...
    FindDialog * dialog;
    QPushButton * findButton;
};
... ...

  补充addressbook.cpp,如下:

... ...
AddressBook :: AddressBook(QWidget * parent) : QWidget(parent)
{
... ...
    findButton = new QPushButton(tr("&Find"));
    findButton->setEnabled(false);
    dialog = new FindDialog();
... ...
    buttonLayout1->addWidget(findButton);
... ...
    connect(findButton, SIGNAL(clicked()),this,SLOT(findContact()));

}

void AddressBook::updateUI(Mode mode){
... ...
    case NavigationMode:
... ...
        findButton -> setEnabled(!contacts.isEmpty());
... ...   

}

void AddressBook::findContact()
{
   dialog->show();
   if(dialog->exec() == QDialog::Accepted){
       QString contactName = dialog->getFindText();
       if(contacts.contains(contactName)){
           nameLine->setText(contactName);
           addressText->setText(contacts.value(contactName));
       }else{
           QMessageBox::information(this,tr("Not Found"), tr("Sorry, %1 is not found").arg(contactName));
       }

   }
}

二进行的文件读写

  我们进一步完善,增加两个button,saveButton和loadButton,将click()信号connect置saveToFile()和loadFromFile(),相关的updateUI修改方式就不在重复,对于一个button,我们还可以采用setToolTip鼠标放在上面,出现提示方式。

loadButton->setToolTip(tr("Load contacts from a file"));
saveButton->setToolTip(tr("Save contacts to a file"));

  我们重点看看save和load,对应写文件和读文件。文件采用QFile,QFile是QIODevice的subclass。通过QFile来open一个文件,如果文件不存在,则创建这个文件。使用 QDataStream来从QIODevice中二进制读写数据。下面是写的例子:

//对于文件类型,假设Address Book类型有两种*.a和*.b,方式为Address Book(*.a *.b),如果多个文件类型,之间使用“;;”来分割
QString fileName = QFileDialog::getOpenFileName(this, tr("Open Address Book"),"",  tr("Address Book(*.abk);;All Files (*)"));
if(fileName.isEmpty())
    return;

QFile file(fileName);
if(file.open(QIODevice::ReadOnly)){
    QDataStream in(&file);
   
contacts.empty();
    in >> contacts; //将in的内容导入contacts。}
}

  下面是读的例子:

    QString fileName = QFileDialog::getSaveFileName(this, tr("Save Address Book"),"", tr("Address Book(*.abk);;All Files (*)"));
    if(fileName.isEmpty())
        return;

    QFile file(fileName);
    if(!file.open(QIODevice::WriteOnly)){
        QMessageBox::information(this,tr("Unable to open file!"), file.errorString());
        return;

    }
    QDataStream out(&file);
    out << contacts;
    file.close();

  在Tutorial的例子中我们发现没有加入close(),close是调用flush后close文件,必须加入的,否则容易出问题。

文本读写方式和String的一些高级用法

  上面是二进制的读写,有时我们需要采用文本text的方式,我们在上面的例子中增加到处vCard格式,并将其保存。我们需要将名字name中区分firstName,llastName。相当于获取一个字符串用空格分隔的第一个字符串和最后一个字符串。

// 其中nameList是QStringList,相当于一个String数组来保存,用split来分开,第二个参数表示如果分割后,entry为空,忽略,例如我们使用;分割,如果有;;,则有一个空的entry,将这个忽略。用户的输入,可能中间隔一个空格,也可能隔两个空格,无论多少个空格我们都作为一个分割符号来处理。这里我们使用了QRegExp来处理。/s表示空格,+表示可以多个。
nameList = name.split(QRegExp("//s+"),QString::SkipEmptyParts);
firstName = nameList.first();  lastName = nameList.last();

  对于文本文件的写,获得有效的QFile file后,如下操作:

    QTextStream out(&file);
    out << "BEGIN:VCARD" << "/n";
    out << "VERSION:2.1" << "/n";
    out << "N:" << lastName <<";" <<firstName <<  "/n"; ... ... //根据vCard格式加,此处略去
    file.close();

  对于close,在我们的实验中,似乎二进制的方式,如果忘记了问题还表示很大,但是文本方式就很有问题。我们编写了一个采用文本方式读文件的函数,如果在write后面(没有close)马上调用之前读函数,读出来为空,如果在write最后有close,则正常。所有我们应该在open之后,加入close。

相关链接:我的MeeGo/Moblin相关文章

0
0
查看评论

Qt例子一 AddressBook测试学习

1. Q 在源代码中是这样定义的: 1 2 # define QT_BEGIN_NAMESPACE namespace QT_NAMESPACE { # define QT_END_NAMESPACE } ...
  • peterli_xue
  • peterli_xue
  • 2016-03-13 23:19
  • 499

【Qt5开发及实例】8、各种对话框!!

1、标准文件对话框 就是点击这个按钮就会打开文件的对话框 具体的实现是: 头文件dialog.h: #include #include #include //网格布局 #include #include #include "inputdlg.h" #i...
  • cutter_point
  • cutter_point
  • 2015-01-01 14:22
  • 3797

关于iOS系统中通讯录的访问

在早些时候,当iOS 6还没出来,我们访问通讯录只要如下简单的代码: ABAddressBookRef addressBook = ABAddressBookCreate(); 不过在iOS 6上,这个API返回空值。苹果提供了如下API: // Call ABAddressBoo...
  • jasonblog
  • jasonblog
  • 2013-01-05 06:36
  • 12835

Qt5官方demo解析集32——Qt Quick Examples - Threading

本系列所有文章可以在这里查看http://blog.csdn.net/cloud_castle/article/category/2123873
  • u011348999
  • u011348999
  • 2014-09-13 16:45
  • 3652

QT(3)对象和继承-Addressbook例子1

隔了几天阴冷,今天下午闪了一丝阳光。   上次我们学习了如何构造一个简单的小例子,既然QT是C++ based,因此需要知晓如何创建一个对象以及实现对象的继承,同时我们对Layout中的QGridLayout进行学习。   在上次的例子中,我们知道如果创建一个不带parent
  • flowingflying
  • flowingflying
  • 2011-01-06 16:51
  • 3456

qt4 创建dialog-----vs vc6.0

1.代码创建 创建一个MainWindow的qt程序,拖一个pushButton到MainWindow上,其click slot如下 void MainWindow::on_pushButton_clicked() { QDialog *dd=new QDialog; dd->show()...
  • luck_good
  • luck_good
  • 2011-11-16 15:39
  • 3814

QT 信号与槽 最简单例子

QT  信号与槽 最简单例子   main.cpp 和 my_head.h源码:   #ifndef MY_HEAD_H #define MY_HEAD_H #include #include //EastonWoo class A : pub...
  • EastonWoo
  • EastonWoo
  • 2013-05-18 20:13
  • 5192

通讯录(AddressBook)3

8.查找通讯录 8.1. 问题   想要在通讯录里查找确定的联系人或者群组。    使用 ABAddressBookCopyArrayOfAllPeople 和 ABAddressBookCopyArrayOfAllGroups 函数来查找通讯录中的全部联系人和群组,遍历返回的数组...
  • safiri
  • safiri
  • 2014-12-12 16:55
  • 453

操作通讯录(AddressBook篇)&通讯录UI(AddressBookUI篇)

iOS开发------操作通讯录(AddressBook篇)&通讯录UI(AddressBookUI篇) iOS 代码GitHub:https://github.com/YRunIntoLove/YAddressBookUIDemo  修改...
  • mn2442304479
  • mn2442304479
  • 2016-08-26 13:31
  • 525

在Qt的dialog中内嵌一个dialog

注意 ChildDialog  是的基类是 QWidget  不是QDialog 1、在子窗体的构造函数中添加: ChildDialog::ChildDialog(QWidget*parent): QDialog(parent), ui(new U...
  • wumingzcj
  • wumingzcj
  • 2017-06-05 10:47
  • 290
    个人资料
    • 访问:4908144次
    • 积分:55333
    • 等级:
    • 排名:第59名
    • 原创:783篇
    • 转载:23篇
    • 译文:237篇
    • 评论:1535条
    博客专栏
    我的公告
    我思故我在,如果一个人无法独立思考,即使熟习各种工具,实质只是工具的一部分,永远无法创造工具。
    文章转载只能用于非商业性质,且不能带有虚拟货币、积分等附加条件;转载必须注明出处。

    我的微博帐号:@恺风Wei
    文章存档