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