我们丰富Addressbook的例子,增加一个Find按键,可弹出一个dialog,参考:http://doc.qt.nokia.com/latest/tutorials-addressbook-part5.html ,http://doc.qt.nokia.com/latest/tutorials-addressbook-part6.html和http://doc.qt.nokia.com/latest/tutorials-addressbook-part7.html,学习下面的内容:
-
QDialog的使用方法。
-
QFileDialog的使用方法
- 二进制和文本的文件读写
- 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相关文章
分享到:
相关推荐
dialog-1.1-9.20080819.1.el6.i686.rpm
前端项目-dialog-polyfill,Polyfill for the dialog element
android dialog-------普通对话框
dialog-based language learning, where supervision is given naturally and implic itly in the response of the dialog partner during the conversation. We study this setup in two domains: the bAbI dataset...
vue-dialog-drag简单的可拖动对话框演示功能:拖放支持(仅用于拖放,不用于拖放)拖放区域组件“ Pin模式”,以锁定vue-dialog-drag简单的可拖动对话框演示功能:拖放支持(仅用于拖动,不用于放置)放置区域组件...
【自定义Dialog】封装IOS样式的Dialog--Android Studio
jquery 弹出窗口插件,包含js中的 alert confirm open 等。
官方离线安装包,测试可用。使用rpm -ivh [rpm完整包名] 进行安装
在artDialog(6.0.0)原始压缩版dialog-plus.js的基础上,增加了对话框的两个选项: 1、【esc】:是否点击键盘[Esc]键退出(默认true); 2、【drag】:是否允许用户拖拽(默认true);
React Native Android Location Services对话框 从Android位置服务打开对话框的React-Native组件安装大多是自动安装(推荐) yarn add react-native-android-location-services-dialog-box 要么npm install react-...
Android自定义Dialog--DanmakuFlame弹幕发送框界面的实现
dialog-1.2-5.20130523.el7.x86_64.rpm,用于CentOS 7.7.1908 系统或者RedHat 7.X 系统 for x86_64使用
这是我的博客《前端常用插件之artDialog弹出框》文章的示例代码 具体使用可参考文章,或者网上搜索也可以
dialog-1.1-10.20080819.el6.x86_64.rpm,用于CentOS 6.10 系统或者RedHat 6.X 系统 for x86_64使用
sweet-alert-dialog-master.zip,太多无法一一验证是否可用,程序如果跑不起来需要自调,部分代码功能进行参考学习。
纯代码编写提示窗,无UI文件。是https://blog.csdn.net/sinat_33419023/article/details/110009514 代码对应的项目文件
(原创)这程序是我用Qt做的,供Qt的入门参考尤其是对Qt的基础知识的学习,还有就是对C++的进一步学习,这中间您能够感受到Qt的神奇之处,领略Qt的魅力,我愿意与您一起去探索Qt的奥妙的,走进Qt的世界和它在一起,...
该程序在MFC实现了基于对话框模式的Dialog-based复制文件的功能,很实用
官方离线安装包,测试可用。使用rpm -ivh [rpm完整包名] 进行安装
Vue元素对话框拖动支持ElementUI对话框拖动用法npm install vue - element - dialog - draggable -- saveimport DlgDraggable from "vue-element-dialog-draggable"Vue . use ( DlgDraggable , { containment : true...