【Qt 文本编辑器】

主要功能概述

实习练习的项目,做一个文本编辑器。在文本框内实现文字的剪切、复制、粘贴;文本高亮部分实现文字加粗、斜体、下划线;文本对齐方式实现居中、靠左、靠右、两端对齐;可以选择字体的颜色、样式和大小;可以选择文字方向(从左到右还是从右到左)。

ui布局如图:

textedit.h包含函数:

class textEdit : public QDialog
{
    Q_OBJECT

public:
    explicit textEdit(QWidget *parent = nullptr);
    ~textEdit();

private:
    Ui::textEdit *ui;
    void setupTextActions();//初始化界面
    void mergeFormatOnWordOrSelection(const QTextCharFormat &format);//对选中字段还是对后面字段生效
    void fontChanged(const QFont &f);//改变字体样式

private slots:
    void textSize(const QString &p);//字体大小
    void textFamily(const QString &f);//字体种类
    void textStyle(int styleIndex);//字体列表标号种类
    void textBold();//加粗
    void textItalic();//斜体
    void textUnderline();//下划线
    void textAlign();//对齐方式
    void textColor();//字体颜色
    void currentCharFormatChanged(const QTextCharFormat &format);//处理格式改变
    void cursorPositionChanged();//处理光标
    void textDirection();//字体向
};

一、界面初始化

在textedit构造函数中,我们要对界面初始化,包括各个控件的连接信号到槽,comboBox中增加元素。其中排列方式对齐、居中、靠右与两端对齐只能取其一,所以将这4个按钮设为按钮组并设置不可同时按下。

textEdit::textEdit(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::textEdit)
{
    ui->setupUi(this);
    this->setLayout(ui->verticalLayout);
    setupTextActions();
    fontChanged(ui->textEdit1->font());//初始字体设置
    ui->textEdit1->setFocus();

    QButtonGroup *btnGroup = new QButtonGroup(this);
    btnGroup->addButton(ui->btnLeft);
    btnGroup->addButton(ui->btnCenter);
    btnGroup->addButton(ui->btnRight);
    btnGroup->addButton(ui->btnJustify);
    btnGroup->setExclusive ( true );

    QObject::connect(ui->textEdit1, SIGNAL(currentCharFormatChanged(const QTextCharFormat &)),
            this, SLOT(currentCharFormatChanged(const QTextCharFormat &)));
    QObject::connect(ui->textEdit1, SIGNAL(cursorPositionChanged()), this, SLOT(cursorPositionChanged()));
    QObject::connect(ui->btnCut, SIGNAL(clicked()), ui->textEdit1, SLOT(cut()));
    QObject::connect(ui->btnCopy, SIGNAL(clicked()), ui->textEdit1, SLOT(copy()));
    QObject::connect(ui->btnPaste, SIGNAL(clicked()), ui->textEdit1, SLOT(paste()));
    QObject::connect(ui->btnDirection, SIGNAL(clicked()), this, SLOT(textDirection()));

}
void textEdit::setupTextActions()
{
    QObject::connect(ui->btnTextBold,SIGNAL(clicked()),this,SLOT(textBold()));
    QObject::connect(ui->btnItalic,SIGNAL(clicked()),this,SLOT(textItalic()));
    QObject::connect(ui->btnUnderLine,SIGNAL(clicked()),this,SLOT(textUnderline()));
    QObject::connect(ui->btnLeft,SIGNAL(clicked()),this,SLOT(textAlign()));
    QObject::connect(ui->btnCenter,SIGNAL(clicked()),this,SLOT(textAlign()));
    QObject::connect(ui->btnRight,SIGNAL(clicked()),this,SLOT(textAlign()));
    QObject::connect(ui->btnJustify,SIGNAL(clicked()),this,SLOT(textAlign()));
    QObject::connect(ui->btnColor,SIGNAL(clicked()),this,SLOT(textColor()));

    ui->comboStyle->addItem(tr("标准"));
    ui->comboStyle->addItem(tr("符号列表(圆点)"));
    ui->comboStyle->addItem(tr("符号列表(圆圈)"));
    ui->comboStyle->addItem(tr("符号列表(方块)"));
    ui->comboStyle->addItem(tr("有序列表(数字)"));
    ui->comboStyle->addItem(tr("有序列表(小写字母)"));

    QObject::connect(ui->comboStyle,SIGNAL(activated(int)),this,SLOT(textStyle(int)));
    QObject::connect(ui->comboFont,SIGNAL(activated(const QString &)),this,SLOT(textFamily(const QString &)));

    ui->comboSize->clear();
    QFontDatabase db;
    foreach(int size,db.standardSizes())
    {
        ui->comboSize->addItem(QString::number(size));
    }
    QObject::connect(ui->comboSize,SIGNAL(activated(const QString &)),this,SLOT(textSize(const QString &)));
   

}

二、对齐方式与打字方向

1、对齐方式改变:

对齐方式改变使用textedit里的函数setAlignment()来设置,代码如下:

void textEdit::textAlign()
{
    if(sender()->objectName()=="btnLeft")
    {
        ui->textEdit1->setAlignment(Qt::AlignLeft|Qt::AlignAbsolute);
    }else if(sender()->objectName()=="btnCenter")
    {
        ui->textEdit1->setAlignment(Qt::AlignCenter);
    }else if(sender()->objectName()=="btnRignt")
    {
        ui->textEdit1->setAlignment(Qt::AlignRight|Qt::AlignAbsolute);
    }else if(sender()->objectName()=="btnJustify")
    {
        ui->textEdit1->setAlignment(Qt::AlignJustify);
    }
}

2、打字方向:

通过判断btnDirection是否被按下来规定当前写作时从左到右还是从右往左(所以在btnDirection被按下,我们希望它保持当前状态,借助光标位置改变发射信号cursorPositionChanged()来实现)。通过QTextOption中的setTextDirection和QTextBlockFormat中的setLayoutDirection实现。

在具体代码如下:

void textEdit::textDirection()
{
    //游标的主要用途是插入或修改块中的文本。我们可以使用文本编辑器的游标来做到这一点:
    //文本文档中有很多文本块,文本块里可以进行设置缩进,行间距,对齐方式。
    //QTextOption是Qt框架中表示文本对齐方式的类,用于控制文本的对齐方式和读写方向。
    QTextCursor cursor=ui->textEdit1->textCursor();
    QTextBlockFormat blockFmt=cursor.blockFormat();
    QTextOption topt=ui->textEdit1->document()->defaultTextOption();

    if(ui->btnDirection->isChecked())
    {
        topt.setTextDirection(Qt::RightToLeft);
        blockFmt.setLayoutDirection(Qt::RightToLeft);
    }
    else{
        topt.setTextDirection(Qt::LeftToRight);
        blockFmt.setLayoutDirection(Qt::LeftToRight);
    }
    ui->textEdit1->document()->setDefaultTextOption(topt);
    cursor.setBlockFormat(blockFmt);
}
void textEdit::cursorPositionChanged()
{
    //alignmentChanged(ui->textEdit1->alignment());
    QTextBlockFormat blockFmt =ui->textEdit1->textCursor().blockFormat();
    if (blockFmt.layoutDirection() == Qt::RightToLeft)
        ui->btnDirection->setChecked(true);
    else
        ui->btnDirection->setChecked(false);
}

三、字体格式改变

判断当前是否选择了字段,以下文字样式改变效果是对block中的所有字生效还是对选中字段生效。

void textEdit::mergeFormatOnWordOrSelection(const QTextCharFormat &format)
{
    QTextCursor cursor=ui->textEdit1->textCursor();
    if(!cursor.hasSelection())
        cursor.select(QTextCursor::WordUnderCursor);
    cursor.mergeCharFormat(format);
    ui->textEdit1->mergeCurrentCharFormat(format);
}

当前字符格式发生改变时,textedit控件会发射currentCharFormatChanged信号,在此信号里实现字体格式的改变:

void textEdit::currentCharFormatChanged(const QTextCharFormat &format)
{
    fontChanged(format.font());
}

字体格式改变包括字体样式、大小、加粗、斜体、下划线的改变:

void textEdit::fontChanged(const QFont &f)
{
    ui->comboFont->setCurrentIndex(ui->comboFont->findText(QFontInfo(f).family()));
    ui->comboSize->setCurrentIndex(ui->comboSize->findText(QString::number(f.pointSize())));
    ui->btnTextBold->setChecked(f.bold());
    ui->btnItalic->setChecked(f.italic());
    ui->btnUnderLine->setChecked(f.underline());
}

1、字体,字号,加粗,倾斜,下划线,颜色

字体样式,字号,加粗,倾斜,下划线,颜色这些都可以用QTextCharFormat类来实现:

字体样式:

void textEdit::textFamily(const QString &f)
{
    QTextCharFormat fmt;
    fmt.setFontFamily(f);
    mergeFormatOnWordOrSelection(fmt);
}

字号:

void textEdit::textSize(const QString &p)
{
    qreal fontSize=p.toFloat();
    if(p.toFloat()>0)
    {
        QTextCharFormat fmt;
        fmt.setFontPointSize(fontSize);
        mergeFormatOnWordOrSelection(fmt);
    }
}

加粗:

void textEdit::textBold()
{
    QTextCharFormat fmt;
    fmt.setFontWeight(ui->btnTextBold->isChecked()?QFont::Bold:QFont::Normal);
    mergeFormatOnWordOrSelection(fmt);
}

倾斜:

void textEdit::textItalic()
{
    QTextCharFormat fmt;
    fmt.setFontItalic(ui->btnItalic->isChecked());
    mergeFormatOnWordOrSelection(fmt);
}

下划线:

void textEdit::textUnderline()
{
    QTextCharFormat fmt;
    fmt.setFontUnderline(ui->btnUnderLine->isChecked());
    mergeFormatOnWordOrSelection(fmt);
}

2、字段标号:

使用QTextListFormat类来选择编号格式,使用QTextCursor中的creatList()实现自动编号。

void textEdit::textStyle(int styleIndex)
{
    QTextCursor cursor=ui->textEdit1->textCursor();
    if (styleIndex != 0) {
        //列表样式
        QTextListFormat::Style style = QTextListFormat::ListDisc;
    switch (styleIndex) {
        default:
        case 1:
            style = QTextListFormat::ListDisc;
            break;
        case 2:
            style = QTextListFormat::ListCircle;
            break;
        case 3:
            style = QTextListFormat::ListSquare;
            break;
        case 4:
            style = QTextListFormat::ListDecimal;
            break;
        case 5:
            style = QTextListFormat::ListLowerAlpha;
            break;
        case 6:
            style = QTextListFormat::ListUpperAlpha;
            break;

    }

    cursor.beginEditBlock();
    QTextBlockFormat blockFmt=cursor.blockFormat();
    QTextListFormat listFmt;
    if(cursor.currentList())
    {
        listFmt=cursor.currentList()->format();
    }else{
        listFmt.setIndent(blockFmt.indent()+1);
        blockFmt.setIndent(0);
        cursor.setBlockFormat(blockFmt);
    }
    listFmt.setStyle(style);
    cursor.createList(listFmt);
    cursor.endEditBlock();
   }else
    {
        QTextBlockFormat blfm;
        blfm.setObjectIndex(-1);
        cursor.mergeBlockFormat(blfm);
    }

}

3、字体颜色:

使用QColorDialog调出调色盘来选择颜色,使用QTextCharFormat中的setForeground来改变字体颜色。

void textEdit::textColor()
{
    QColor color;
    QColorDialog *dlg=new QColorDialog(this);
    if(dlg->exec()==QDialog::Accepted){
        color=dlg->selectedColor();
    }else return;
    QTextCharFormat fmt;
    fmt.setForeground( QBrush( color ) );
    mergeFormatOnWordOrSelection(fmt);
}

四、最终效果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值