5.3 Qt5排版功能

5.3 排版功能的实现

  排版功能的实现,也和QTextEdit中的QTextDocument的QTextFrame、QTextTable、QTextList、QTextBlock以及描述这些内容的QTextCharFormat、QTextFrameFormat、QTextTableFormat、QTextListFormat、QTextBlockFormat密切相关。

  为了完成这些功能,我们需要添加一个QLabel、QComboBox、QActionGroup、以及用于描述左对齐、右对齐、居中对齐和两端对齐的四个QAction以及用于容纳这些控件的一个QToolBar。

  对齐功能的实现:

    对齐功能需要使用到QTextEdit里面的setAligenment方法来进行对当前打开的文档视图进行对齐操作。具体需要使用到对齐属性的以下几个枚举值

Qt::AlignmentFlag::AlignLeft //左对齐
Qt::AlignmentFlag::AlignCenter //居中对齐
Qt::AlignmentFlag::AlignRight //右对齐
Qt::AlignmentFlag::AlignJustify //两端对齐(自适应对齐)

  在imgprocessor.h中添加以下内容

private:
    QLabel*m_sortLabel;
    QComboBox*m_sortComboBox;
    QActionGroup*m_sortActionGroup;
    QAction*m_leftAction;
    QAction*m_centerAction;
    QAction*m_rightAction;
    QAction*m_justifyAction;
    QToolBar*m_sortToolBar;
private:
    void createSortWidget();//创建和排版有关的Widget
private slots:
    void ShowList(int);
    void ShowAlignment(QAction*);
    void ShowCursorPositionChanged();

  在imgprocessor.cpp中实现成员函数

void ImgProcessor::createSortWidget()
{
    m_sortLabel = new QLabel(tr("排序"));//Label,用于在ComboBox前面显示'排序'两个字

    m_sortComboBox = new QComboBox;//ComboBox,用于描述排序的方式
    m_sortComboBox->addItem("Standard");
    m_sortComboBox->addItem("QTextListFormat::ListDisc");
    m_sortComboBox->addItem("QTextListFormat::ListCircle");
    m_sortComboBox->addItem("QTextListFormat::ListSquare");
    m_sortComboBox->addItem("QTextListFormat::ListDecimal");
    m_sortComboBox->addItem("QTextListFormat::ListLowerAlpha");
    m_sortComboBox->addItem("QTextListFormat::ListUpperAlpha");
    m_sortComboBox->addItem("QTextListFormat::ListLowerRoman");
    m_sortComboBox->addItem("QTextListFormat::ListUpperRoman");

    m_sortActionGroup = new QActionGroup(this);//ActionGroup,可以理解为专门用来管理多个QAction的一种容器
    m_leftAction = new QAction(QIcon(":/left.png"),"左对齐",m_sortActionGroup);
    m_leftAction->setCheckable(true);
    m_centerAction = new QAction(QIcon(":/center.png"),"居中对齐",m_sortActionGroup);
    m_centerAction->setCheckable(true);
    m_rightAction = new QAction(QIcon(":/right.png"),"右对齐",m_sortActionGroup);
    m_rightAction->setCheckable(true);
    m_justifyAction = new QAction(QIcon(":/side.png"),"两端对齐",m_sortActionGroup);
    m_justifyAction->setCheckable(true);

    m_sortToolBar = new QToolBar(QString("排版"),this);
    m_sortToolBar->addWidget(m_sortLabel);
    m_sortToolBar->addWidget(m_sortComboBox);
    m_sortToolBar->addSeparator();
    m_sortToolBar->addActions(m_sortActionGroup->actions());//把ActionGroup里面的所有的Action添加到ToolBar里面

    this->addToolBar(m_sortToolBar);

    //事件关联
    connect(this->m_sortComboBox,SIGNAL(activated(int)),this,SLOT(ShowList(int)));
    connect(this->m_sortActionGroup,SIGNAL(triggered(QAction*)),this,SLOT(ShowAlignment(QAction*)));
    connect(this->m_showWidget->m_text,&QTextEdit::cursorPositionChanged,this,&ImgProcessor::ShowCursorPositionChanged);
    connect(this->m_showWidget->m_text->document(),SIGNAL(redoAvailable(bool)),this->m_redoAction,SLOT(setEnabled(bool)));//这一个信号和槽是用来描述当前文档是否可以进行进行还原操作,如果可以,那么按钮就不是灰色,反正则是灰色
    connect(this->m_showWidget->m_text->document(),SIGNAL(undoAvailable(bool)),this->m_undoAction,SLOT(setEnabled(bool)));//描述的是撤销操作是否可以被执行
}

void ImgProcessor::ShowList(int index)
{
    /*
     * 描述文本排序格式的QTextListFormat包含两个基本属性,一个是排序的方式:
     * QTextListFormat::Sytle里面的一些内容
     * 另一个则是排序后的文字和文字之间的缩进值,那么我们就只需要设置QTextCursor里面的这两个内容然后设置回到QTextEdit中即可
     * 具体来说,设置Style则是需要设置QTextEdit里面的textcursor中的currentList中的format的Style属性
     * 而如果需要设置缩进值,这里实际上文本编辑器里面默认就有一个缩进值,但是为了演示应该如何去设置,实际上需要获取整个文本块的
     * 缩进值,然后在这个缩进值的基础上加1然后设置到QTextListFormat上
    */
    QTextCursor cursor = m_showWidget->m_text->textCursor();//获取textCursor
    QTextListFormat::Style style = QTextListFormat::Style::ListDisc;
    // 1.获取用户所选择的排序方式
    if("Standard" == m_sortComboBox->itemText(index))
    {
        style = QTextListFormat::Style::ListDisc;
    }
    else if("QTextListFormat::ListDisc" == m_sortComboBox->itemText(index))
    {
        style = QTextListFormat::Style::ListDisc;
    }
    else if("QTextListFormat::ListCircle" == m_sortComboBox->itemText(index))
    {
        style = QTextListFormat::Style::ListCircle;
    }
    else if("QTextListFormat::ListSquare" == m_sortComboBox->itemText(index))
    {
        style = QTextListFormat::Style::ListSquare;
    }
    else if("QTextListFormat::ListDecimal" == m_sortComboBox->itemText(index))
    {
        style = QTextListFormat::Style::ListDecimal;
    }
    else if("QTextListFormat::ListLowerAlpha" == m_sortComboBox->itemText(index))
    {
        style = QTextListFormat::Style::ListLowerAlpha;
    }
    else if("QTextListFormat::ListUpperAlpha" == m_sortComboBox->itemText(index))
    {
        style = QTextListFormat::Style::ListUpperAlpha;
    }
    else if("QTextListFormat::ListLowerRoman" == m_sortComboBox->itemText(index))
    {
        style = QTextListFormat::Style::ListLowerRoman;
    }
    else if("QTextListFormat::ListUpperRoman" == m_sortComboBox->itemText(index))
    {
        style = QTextListFormat::Style::ListUpperRoman;
    }
    // 2.设置ListFormat
    /*
     * 这里在设置ListFormat时,需要先判断cursor所选择编辑的文本是否是有效的Textlist,如果有效,那么
     * 我们只需要获取到这里的format然后,直接将其改为用户所选择的Style即可。如果没有(比如是空行的情况),
     * 那么我们就需要获取当前编辑框的文本块,然后根据文本块的属性来对应设置一个新的ListFormat,然后对cursor
     * 来进行设置
    */
    QTextListFormat listFormat;
    cursor.beginEditBlock();
    if(cursor.currentList())
    {
        listFormat = cursor.currentList()->format();
    }
    else
    {
        QTextBlockFormat blockFormat = cursor.blockFormat();
        listFormat.setIndent(blockFormat.indent()+1);//为了看出效果,这里设置缩进为原来文本块的缩进值加一
    }
    listFormat.setStyle(style);
    cursor.createList(listFormat);
    cursor.endEditBlock();
}

void ImgProcessor::ShowAlignment(QAction *action)
{
    if("左对齐" == action->text())
    {
        m_showWidget->m_text->setAlignment(Qt::AlignmentFlag::AlignLeft);
    }
    else if("居中对齐" == action->text())
    {
        m_showWidget->m_text->setAlignment(Qt::AlignmentFlag::AlignCenter);
    }
    else if("右对齐" == action->text())
    {
        m_showWidget->m_text->setAlignment(Qt::AlignmentFlag::AlignRight);
    }
    else if("两端对齐" == action->text())
    {
        m_showWidget->m_text->setAlignment(Qt::AlignmentFlag::AlignJustify);
    }
}

void ImgProcessor::ShowCursorPositionChanged()
{
    //当我们已经设置了对齐方式的时候,需要将对齐方式对应的按钮进行高亮,也就是需要进行setCheckable操作
    switch (m_showWidget->m_text->alignment())
    {
    case Qt::AlignmentFlag::AlignLeft:
        m_leftAction->setChecked(true);//对于按钮,如果需要实现Checkable操作,就需要将按钮设置上setCheckabeled属性
        break;
    case Qt::AlignmentFlag::AlignRight:
        m_rightAction->setChecked(true);
        break;
    case Qt::AlignmentFlag::AlignCenter:
        m_centerAction->setChecked(true);
        break;
    case Qt::AlignmentFlag::AlignJustify:
        m_justifyAction->setChecked(true);
        break;
    }

}

  最终效果图

  本节代码:https://files.cnblogs.com/files/blogs/792763/ImageProcessor5.3.zip?t=1716626626&download=true

posted @ 2024-05-25 16:44  蜡笔小新Pointer  阅读(50)  评论(0)    收藏  举报