Qt——查找对话框的功能实现

1.QString类中提供了子串查找的相关函数

(1)indexOf:从指定位置向后查找目标子串的下标位置

(2)lastIndexOf:从指定位置向前查找目标子串的下标位置

2.Qt中的光标信息类QTextCursor

  • 文本框中的光标是一个QTextCursor对象

  • 所有与光标相关的信息都通过QTextCursor描述,如光标位置、文本选择等

    QTextCursor c = mainEditor.textCursor(); //获取当前光标
    c.setPosition(1); // 定位到下标1的位置
    c.setPosition(4, QTextCursor::KeepAnchor); // 文本选择范围[1,4]
    mainEditor.setTextCursor(c); //设置光标信息到文本框

FindDialog.h

复制代码
#include <QCheckBox>
#include <QGroupBox>
#include <QPlainTextEdit>
#include <QPointer>

class FindDialog : public QDialog
{
    Q_OBJECT

protected:
    QGridLayout m_layout;
    QHBoxLayout m_hbLayout;
    QGroupBox m_radioGrpBx;
    QLabel m_findLbl;
    QLineEdit m_findEdit;
    QPushButton m_findBtn;
    QPushButton m_closeBtn;
    QCheckBox m_matchChkBx;
    QRadioButton m_forwardBtn;
    QRadioButton m_backwardBtn;

    QPointer<QPlainTextEdit> m_pText; //声明一个专用于观察 QPlainTextEdit 控件的智能指针
    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 <QEvent>
#include <QTextCursor>
#include <QMessageBox>

FindDialog::FindDialog(QWidget* parent, QPlainTextEdit* pText) : QDialog(parent, Qt::WindowCloseButtonHint | Qt::Drawer)
{
    initControl();
    connectSlot();
    setLayout(&m_layout);
    setWindowTitle("Find");
    setPlainTextEdit(pText);
}
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::initControl()
{
    m_findLbl.setText("Find What: ");
    m_findBtn.setText("Find Next");
    m_closeBtn.setText("Close");
    m_matchChkBx.setText("Matc h Case");
    m_backwardBtn.setText("Backward");
    m_forwardBtn.setText("Forward");
    m_forwardBtn.setChecked(true);
    m_radioGrpBx.setTitle("Direction");

    m_hbLayout.addWidget(&m_backwardBtn);
    m_hbLayout.addWidget(&m_forwardBtn);

    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::onFindClicked()
{
    QString target = m_findEdit.text();  // 213
    if((m_pText != NULL) && (target != ""))
    {
        QString text = m_pText->toPlainText();      // 21312312312213123123123
        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);
                //KeepAnchor 就是代码中的 "按住 Shift 键"。
                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.setStandardButtons(QMessageBox::Ok);
            msg.exec();
        }
    }
}
void FindDialog::onCloseClicked()
{
    close();
}
相关推荐
从小就看凹凸曼^o^1 小时前
Python基础5 - 字典与集合:(1)字典
开发语言·python
侧耳倾听1111 小时前
java 日志框架简介
java·开发语言
zlinear数据采集卡1 小时前
数据采集卡从入门到精通(9):分辨率与精度——16位卡不等于1/65536的精度
开发语言·数据库·fpga开发·开源·c#
全栈技术负责人2 小时前
解密 MCP(Model Context Protocol):大模型时代的“Type-C”总线与三驾马车架构深度解析
开发语言·ai·架构
丰锋ff2 小时前
1.7在Qt窗口中添加右键菜单
开发语言·qt
Titan20242 小时前
Linux网络学习:套接字、UDP的封装与应用
linux·服务器·开发语言·网络·c++
鸿芯微控科技3 小时前
压电点胶阀出胶量不稳定怎么排查?驱动波形、背压、点胶重量与Python分析
开发语言·python·压电点胶阀·精密点胶·点胶重量·流体控制
原野池予3 小时前
深入Java集合框架:HashMap源码解析(JDK 8)
java·开发语言
Logintern093 小时前
asyncio里面的await理解
开发语言·python
测试运维日常笔记3 小时前
VMware vSphere、ESXi 与 vCenter Server:核心概念与关系详解
java·开发语言