目录
1、查找对话框的实现
2、替换对话框的实现
1、查找对话框
查找对话框是应用程序中的常用部件
目标: 开发一个可以在不同项目间复用的查找对话框
查找对话框需求分析
-可复用软件部件
-查找文本框中的指定字符串
-能够指定查找方向
-支持大小写敏感查找
- 点击关闭按钮后隐藏
查找对话框的架构与设计
查找对话框的界面布局
2、编程实验
查找对话框界面开发
FindDialog.h
#ifndef _FINDDIALOG_H_
#define _FINDDIALOG_H_
#include
#include
#include
#include
#include
#include
#include
#include
#include
class FindDialog : public QDialog
{
Q_OBJECT
protected:
QGroupBox m_radioGrpBx;
QGridLayout m_layout;
QHBoxLayout m_hbLayout;
QLabel m_findLbl;
QLineEdit m_findEdit;
QPushButton m_findBtn;
QPushButton m_closeBtn;
QCheckBox m_matchChkBx;
QRadioButton m_forwardBtn;
QRadioButton m_backwardBtn;
public:
explicit FindDialog(QWidget* parent = 0);
bool event(QEvent* evt);
signals:
public slots:
};
#endif // _FINDDIALOG_H_
FindDialog.cpp
#include "FindDialog.h"
#include
FindDialog::FindDialog(QWidget *parent) : QDialog(parent, Qt::WindowCloseButtonHint | Qt::Drawer)
{
m_findLbl.setText("Find What:");
m_findBtn.setText("Find Next");
m_closeBtn.setText("Close");
m_matchChkBx.setText("Match Case");
m_backwardBtn.setText("Backward");
m_forwardBtn.setText("Forward");
m_forwardBtn.setChecked(true);
m_radioGrpBx.setTitle("Direction");
m_hbLayout.addWidget(&m_forwardBtn);
m_hbLayout.addWidget(&m_backwardBtn);
m_radioGrpBx.setLayout(&m_hbLayout);
m_layout.setSpacing(10);
m_layout.addWidget(&m_findLbl, 0, 0);
m_layout.addWidget(&m_findEdit, 0, 1);
m_layout.addWidget(&m_findBtn, 0, 2);
m_layout.addWidget(&m_matchChkBx, 1, 0);
m_layout.addWidget(&m_radioGrpBx, 1, 1);
m_layout.addWidget(&m_closeBtn, 1, 2);
setLayout(&m_layout);
setWindowTitle("Find");
}
bool FindDialog::event(QEvent* evt)
{
if( evt->type() == QEvent::Close )
{
hide();
return true;
}
return QDialog::event(evt);
}
3、查找功能的实现
文本查找功能的核心思想
1. 获取当前光标的位置并作为起始点
2. 向后(向前)查找目标第一次出现的位置
3. 通过目标位置以及目标长度在文本框中进行标记
QString类中提供了子串查找的相关函数
- indexOf
从指定位置向后查找目标子串的下标位置
- lastIndexOf
从指定位置向前查找目标子串的下标位置
Qt中的光标信息类QTextCursor
- 文本框中的光标是一个QTextCursor对象
- 所有与光标相关的信息都通过QTextCursor描述
• 如:光标位置,文本选择,等等
查找算法流程图
MainWindow与FindDialog之间的关系图
4、编程实验
查找功能的实现
FindDialog.h
#ifndef _FINDDIALOG_H_
#define _FINDDIALOG_H_
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
class FindDialog : public QDialog
{
Q_OBJECT
protected:
QGroupBox m_radioGrpBx;
QGridLayout m_layout;
QHBoxLayout m_hbLayout;
QLabel m_findLbl;
QLineEdit m_findEdit;
QPushButton m_findBtn;
QPushButton m_closeBtn;
QCheckBox m_matchChkBx;
QRadioButton m_forwardBtn;
QRadioButton m_backwardBtn;
QPointer m_pText;
void initControl();
void connectSlot();
protected slots:
void onFindClicked();
void onCloseClicked();
public:
explicit FindDialog(QWidget* parent = 0, QPlainTextEdit* pText = 0);
void setPlainTextEdit(QPlainTextEdit* pText);
QPlainTextEdit* getPlainTextEdit();
bool event(QEvent* evt);
};
#endif // _FINDDIALOG_H_
FindDialog.cpp
#include "FindDialog.h"
#include
#include
#include
FindDialog::FindDialog(QWidget *parent, QPlainTextEdit* pText)
: QDialog(parent, Qt::WindowCloseButtonHint | Qt::Drawer)
{
initControl();
connectSlot();
setLayout(&m_layout);
setWindowTitle("Find");
setPlainTextEdit(pText);
}
void FindDialog::initControl()
{
m_findLbl.setText("Find What:");
m_findBtn.setText("Find Next");
m_closeBtn.setText("Close");
m_matchChkBx.setText("Match Case");
m_backwardBtn.setText("Backward");
m_forwardBtn.setText("Forward");
m_forwardBtn.setChecked(true);
m_radioGrpBx.setTitle("Direction");
m_hbLayout.addWidget(&m_forwardBtn);
m_hbLayout.addWidget(&m_backwardBtn);
m_radioGrpBx.setLayout(&m_hbLayout);
m_layout.setSpacing(10);
m_layout.addWidget(&m_findLbl, 0, 0);
m_layout.addWidget(&m_findEdit, 0, 1);
m_layout.addWidget(&m_findBtn, 0, 2);
m_layout.addWidget(&m_matchChkBx, 1, 0);
m_layout.addWidget(&m_radioGrpBx, 1, 1);
m_layout.addWidget(&m_closeBtn, 1, 2);
}
void FindDialog::connectSlot()
{
connect(&m_findBtn, SIGNAL(clicked()), this, SLOT(onFindClicked()));
connect(&m_closeBtn, SIGNAL(clicked()), this, SLOT(onCloseClicked()));
}
void FindDialog::setPlainTextEdit(QPlainTextEdit* pText)
{
m_pText = pText;
}
QPlainTextEdit* FindDialog::getPlainTextEdit()
{
return m_pText;
}
bool FindDialog::event(QEvent* evt)
{
if( evt->type() == QEvent::Close )
{
hide();
return true;
}
return QDialog::event(evt);
}
void FindDialog::onFindClicked()
{
QString target = m_findEdit.text();
if( (m_pText != NULL) && (target != "") )
{
QString text = m_pText->toPlainText();
QTextCursor c = m_pText->textCursor();
int index = -1;
if( m_forwardBtn.isChecked() )
{
index = text.indexOf(target, c.position(), m_matchChkBx.isChecked() ? Qt::CaseSensitive : Qt::CaseInsensitive);
if( index >= 0 )
{
c.setPosition(index);
c.setPosition(index + target.length(), QTextCursor::KeepAnchor);
m_pText->setTextCursor(c);
}
}
if( m_backwardBtn.isChecked() )
{
index = text.lastIndexOf(target, c.position() - text.length() - 1, m_matchChkBx.isChecked() ? Qt::CaseSensitive : Qt::CaseInsensitive);
if( index >= 0 )
{
c.setPosition(index + target.length());
c.setPosition(index, QTextCursor::KeepAnchor);
m_pText->setTextCursor(c);
}
}
if( index < 0 )
{
QMessageBox msg(this);
msg.setWindowTitle("Find");
msg.setText("Can not find \"" + target + "\" any more...");
msg.setIcon(QMessageBox::Information);
msg.setStandardButtons(QMessageBox::Ok);
msg.exec();
}
}
}
void FindDialog::onCloseClicked()
{
close();
}
使用该查找对话框类
MainWindow.h
QSharedPointer m_pFindDlg;
MainWindowUI.cpp
MainWindow::MainWindow() : m_pFindDlg(new FindDialog(this, &mainEditor))
{
//mainEditor为文本编辑框对象
}
高亮显示的颜色问题
QPalette p = mainEditor.palette();
p.setColor(QPalette::Inactive, QPalette::Highlight, p.color(QPalette::Active, QPalette::Highlight));
p.setColor(QPalette::Inactive, QPalette::HighlightedText, p.color(QPalette::Active, QPalette::HighlightedText));
mainEditor.setPalette(p);
5、小结
查找对话框可以作用一个可复用的软件部件进行开发
查找对话框继承自QDialog类
查找对话框的界面通过布局管理器相互嵌套完成
查找对话框的设计与实现是GUI学习中的经典范例
QString中提供了不同的子串查找方式
QTextCursor对象保存了文本框中光标的相关信息
QString对象和QTextCurosr对象协作实现查找功能
查找对话框与文本框的弱耦合关系满足了可复用的需求
1、替换对话框
替换对话框需求分析
-可复用软件部件
-查找文本框中的指定字符串
-替换单个指定字符串
-替换所有指定字符串
-点击关闭按钮后隐藏
替换对话框的设计与实现
替换对话框的界面布局
第一行的布局可以直接继承自FindDialog
2、查找功能的实现
MainWindow与ReplaceDialog之间的关系图
3、编程实验
ReplaceDialog.h
#ifndef _REPLACEDIALOG_H_
#define _REPLACEDIALOG_H_
#include "FindDialog.h"
class ReplaceDialog : public FindDialog
{
Q_OBJECT
protected:
QLabel m_replaceLbl;
QLineEdit m_replaceEdit;
QPushButton m_replaceBtn;
QPushButton m_replaceAllBtn;
void initControl();
void connectSlot();
protected slots:
void onReplaceClicked();
void onReplaceAllClicked();
public:
explicit ReplaceDialog(QWidget *parent = 0, QPlainTextEdit* pText = 0);
};
#endif // _REPLACEDIALOG_H_
ReplaceDialog.cpp
#include "ReplaceDialog.h"
ReplaceDialog::ReplaceDialog(QWidget *parent, QPlainTextEdit* pText) :
FindDialog(parent, pText)
{
initControl();
connectSlot();
setWindowTitle("Replace");
}
void ReplaceDialog::initControl()
{
m_replaceLbl.setText("Replace To:");
m_replaceBtn.setText("Replace");
m_replaceAllBtn.setText("Replace All");
m_layout.removeWidget(&m_matchChkBx);
m_layout.removeWidget(&m_radioGrpBx);
m_layout.removeWidget(&m_closeBtn);
m_layout.addWidget(&m_replaceLbl, 1, 0);
m_layout.addWidget(&m_replaceEdit, 1, 1);
m_layout.addWidget(&m_replaceBtn, 1, 2);
m_layout.addWidget(&m_matchChkBx, 2, 0);
m_layout.addWidget(&m_radioGrpBx, 2, 1);
m_layout.addWidget(&m_replaceAllBtn, 2, 2);
m_layout.addWidget(&m_closeBtn, 3, 2);
}
void ReplaceDialog::connectSlot()
{
connect(&m_replaceBtn, SIGNAL(clicked()), this, SLOT(onReplaceClicked()));
connect(&m_replaceAllBtn, SIGNAL(clicked()), this, SLOT(onReplaceAllClicked()));
}
void ReplaceDialog::onReplaceClicked()
{
QString target = m_findEdit.text();
QString to = m_replaceEdit.text();
if( (m_pText != NULL) && (target != "") && (to != "") )
{
QString selText = m_pText->textCursor().selectedText();//第一次没有选择任何文本
if( selText == target )
{
m_pText->insertPlainText(to);
}
onFindClicked();//第一次不会替换,会查找,符合Windows上的记事本替换准则
}
}
void ReplaceDialog::onReplaceAllClicked()
{
QString target = m_findEdit.text();
QString to = m_replaceEdit.text();
if( (m_pText != NULL) && (target != "") && (to != "") )
{
QString text = m_pText->toPlainText();
text.replace(target, to, m_matchChkBx.isChecked() ? Qt::CaseSensitive : Qt::CaseInsensitive);
m_pText->clear();
m_pText->insertPlainText(text);
}
}
4、小结
替换对话框的功能涵盖了查找对话框的功能
替换对话框可以继承自查找对话框
替换功能的实现是基于查找算法完成的
替换对话框是一个可复用的软件部件