一、查找功能的实现
1、文本查找功能的核心思想
(1)、获取当前光标的位置并作为起始点
(2)、向前(向后)查找目标第一次出现的位置
(3)、通过目标位置以及目标长度在文本框中进行标记
2、QString提供了子串查找的相关函数
(1)、indexOf:从指定位置向后查找目标子串下标位置
(2)、lastIndexOf:从指定位置向前查找目标子串下标位置
3、QString类中查找函数所使用的下标位置
4、Qt中的光标信息类QTextCursor
(1)、文本框中的光标是一个QTextCursor类的对象
(2)、所有与光标相关的信息都通过QTextCursor描述(如光标位置、文本选择等)
5、查找算法流程图
6、MainWindow和FindDialog之间的关系(为了实现弱耦合,使FindDialog内部一个指针指向QPlainTextEdit即可)
实现的具体步骤:
1、为了简化构造函数,就把一些初始化的东西抽取出来封装到一个函数

void FindDialog::initControl() { m_findLabel.setText("查找内容: "); // m_findButton.setEnabled(false); m_findButton.setText("查找下一个"); m_checkBox.setText("区分大小写"); m_forwardButton.setText("向上"); m_backwardButton.setChecked(true); m_backwardButton.setText("向下"); m_cancleButton.setText("取消"); m_gBox.setTitle("方向"); m_hLayout.addWidget(&m_forwardButton); m_hLayout.addWidget(&m_backwardButton); m_gBox.setLayout(&m_hLayout); m_gLayout.setSpacing(10); m_gLayout.addWidget(&m_findLabel, 0, 0); m_gLayout.addWidget(&m_findLineEdit, 0, 1); m_gLayout.addWidget(&m_findButton, 0, 2); m_gLayout.addWidget(&m_checkBox, 1, 0); m_gLayout.addWidget(&m_gBox, 1, 1); m_gLayout.addWidget(&m_cancleButton, 1, 2); }
2、为了实现弱耦合,FindDialog里定义一个指向QPlainTextEdit的指针,通过构造函数传进来(并定义get和set函数来做相关操作)
3、定义槽函数并在构造函数中连接信号与槽
4、编写槽函数

void FindDialog::setPlainTextEdit(QPlainTextEdit* pText) { m_plainTextEdit = pText; } QPlainTextEdit* FindDialog::getPlainTextEdit() { return m_plainTextEdit; } void FindDialog::onFindButtonClicked() { QString target = m_findLineEdit.text(); if((m_plainTextEdit != NULL) && (target != "")) { QString text = m_plainTextEdit->toPlainText(); QTextCursor c = m_plainTextEdit->textCursor(); int index = -1; if(m_backwardButton.isChecked()) { index = text.indexOf(target, c.position(), m_checkBox.isChecked()? Qt::CaseSensitive : Qt::CaseInsensitive); if(index >=0 ) { c.setPosition(index); c.setPosition(index + target.length(), QTextCursor::KeepAnchor); m_plainTextEdit->setTextCursor(c);//将光标信息设置到文本框里面才能看见效果 } } if(m_forwardButton.isChecked()) { index = text.lastIndexOf(target, c.position() - text.length() - 1, m_checkBox.isChecked()? Qt::CaseSensitive : Qt::CaseInsensitive);//注意下标为负数 if(index >=0 ) { c.setPosition(index + target.length()); c.setPosition(index, QTextCursor::KeepAnchor);//注意后往前找到后设置光标的方法 m_plainTextEdit->setTextCursor(c); } } if(index < 0) { QMessageBox dlg(this); dlg.setText("找不到" + target); dlg.setStandardButtons(QMessageBox::Ok); dlg.setIcon(QMessageBox::Information); dlg.setWindowTitle("查找5"); dlg.exec(); } } } void FindDialog::onCancleButtonClicked() { close(); }
5、记得调用FindDialog构造函数时传多一个参数
二、小结
(1)、QString提供了不同的子串查找方式
(2)、QTextCursor对象保存了文本框中光标的相关信息
(3)、QString对象和QTextCursor对象协作实现查找功能
(4)、查找对话框和文本框的弱耦合关系满足了可复用的需求