QT5主窗体

这里通过一个文本编辑器的应用实例来介绍QMainWindow主窗体的各种功能的开发。

1 基本元素

    QMainWindow是一个为用户提供主窗口程序的类,包含一个菜单栏(menu bar)、多个工具栏(tool bars)、多个锚接部件(dock widgets)、一个状态栏(status bar)及一个中心部件(central widget),是许多应用程序的基础,如文本编辑器、图片编辑器等。

2 Qt5文件操作功能

2.1 新建文件

实现新建文件功能的函数ShowNewFile()如下:

void ImgProcessor::ShowNewFile()
{    
    ImgProcessor *newImgProcessor =new ImgProcessor;    
    newImgProcessor->show();
}

2.2 打开文件

实现打开文件功能的函数ShowOpenFile()如下:

void ImgProcessor::ShowOpenFile()
{
   fileName = QFileDialog::getOpenFileName(this);   
    if(!fileName.isEmpty())    
    {       
         if(showWidget->text->document()->isEmpty())        
        {            
            loadFile(fileName);        
        }       
         else       
         {           
             ImgProcessor *newImgProcessor =new ImgProcessor;            
             newImgProcessor->show();            
             newImgProcessor->loadFile(fileName);        
          }    
      }
}

其中,loadFile()函数的实现如下,该函数利用QFileQTextStream完成具体读取文件内容的工作:

void ImgProcessor::loadFile(QString filename)
{    
    printf("file name:%s\n",filename.data());      
    QFile file(filename);    
    if(file.open(QIODevice::ReadOnly|QIODevice::Text))    
    {        
        QTextStream textStream(&file);        
        while(!textStream.atEnd())        
        {            
            showWidget->text->append(textStream.readLine());            
            printf("read line\n");        
        }        
        printf("end\n");    
    }
}

在此仅详细说明标准文件对话框QFileDialog的getOpenFileName()静态函数各个参数的作用,其他文件对话框类中相关的静态函数的参数有与其类似之处。

QString QFileDialog::getOpenFileName
(
QWidget* parent=0,                                  //定义标准文件对话框的父窗口
const QString & caption=QString(),         //定义标准文件对话框的标题名
const QString & dir=QString(),                 //指定默认目录
const QString & filter=QString(),              //对文件类型进行过滤,只有与过滤匹配的文件类型才显示
QString * selectedFilter=0,                        //用户选择的过滤器通过此参数返回
Options options=0
);

2.3 打印文件

    打印文本在文本编辑工作中经常使用,OPrintDialog标准对话框提供了打印机的选择、配置功能,并允许使用者改变文档有关的设置,如页面范围、打印份数等。Qt5中将QPrinter、QPrintDialog等类归入到了printsupport模块中,使用时要在.pro文件中加“QT += printsupport”。

2.3.1 文本打印

实现打印文本功能的函数ShowPrintText ()如下:

void ImgProcessor::ShowPrintText()
{    
    QPrinter printer;    
    QPrintDialog printDialog(&printer, this);     //创建一个QPrintDialog对象,参数为QPinter对象
    if(printDialog.exec())                                      //判断用户是否单击“打印”按钮
    {        
        QTextDocument *doc =showWidget->text->document();        
        doc->print(&printer);    
    }
}

2.3.2 图像打印

实现打印图像功能的函数ShowPrintImage ()如下:

void ImgProcessor::ShowPrintImage()
{        
    QPrinter printer;    
    QPrintDialog printDialog(&printer,this);    
    if(printDialog.exec())                                      //判断用户是否点击了"打印“按钮
    {        
        QPainter painter(&printer);        
        QRect rect =painter.viewport();                 //获取QPianter对象的视口矩形区域
        QSize size = img.size();                              //获取图像的大小
        size.scale(rect.size(),Qt::KeepAspectRatio);          
        painter.setViewport(rect.x(),rect.y(),size.width(),size.height());         //按照图形的比例大小重新设置视口矩形区域
        painter.setWindow(img.rect());                  //设置QPainter窗口大小为图像的大小
        painter.drawImage(0,0,img);                      //打印图像
    }
}

3 Qt5图像座标变换功能

    QMatrix类提供了世界座标系统的二维转换功能,可以使窗体转换变形,经常在绘图程序中使用,还可以实现座标系统的移动、缩放、变形及旋转功能。

3.1 缩放功能

实现图形放大功能的函数ShowZoomIn()如下:

void ImgProcessor::ShowZoomIn()
{    
    if(img.isNull())               //有效性判断
        return;    
    QMatrix martix;    
    martix.scale(2,2);            //按照两倍比例对水平和垂直方向进行放大,缩小两倍改为(0.5, 0.5)即可
    img = img.transformed(martix);              //将当前显示的图形按照该座标矩阵进行转换
    showWidget->imageLabel->setPixmap(QPixmap::fromImage(img));                //重新设置显示图形
}

3.2 旋转功能

实现90度旋转功能的ShowRotate90()函数的具体实现代码如下:

void ImgProcessor::ShowRotate90()
{    
    if(img.isNull())        
        return;    
    QMatrix matrix;    
    matrix.rotate(90);    
    img = img.transformed(matrix);    
    showWidget->imageLabel->setPixmap(QPixmap::fromImage(img));
}

3.3 镜像功能

    通过QImage::mirroored(bool horizontal, bool vertical)实现图形的镜像功能,参数horizontal和vertical分别指定了镜像的方向。

ShowMirrorVertical ()、ShowMirrorHorizontal ()函数的具体实现代码如下:

void ImgProcessor::ShowMirrorVertical()
{    
    if(img.isNull())        
        return;    
    img=img.mirrored(false,true);    
    showWidget->imageLabel->setPixmap(QPixmap::fromImage(img));
}
void ImgProcessor::ShowMirrorHorizontal() 
{    
    if(img.isNull())        
        return;    
    img=img.mirrored(true,false);    
    showWidget->imageLabel->setPixmap(QPixmap::fromImage(img)); 
} 

4 Qt5文本编辑功能

    在编写包含格式设置的文本编辑程序时,经常用到的Qt类有QTextEdit、QTextDocument、QTextBlock、QTextList、QTextFrame、QTextTable、QTextCharFormat、QTextBlockFormat、QTextFrameFormat和QTextTableFormat等,各类之间的划分与关系如下图所示。

    

    任何一个文本编辑的程序都要用到QTextEdit作为输入文本的容器,在它里面输入可编辑文本由QTextDocument作为载体,而用来便是QTextDocument的元素QTextBlock、QTextList、QTextFrame等是QTextDocument的不同表现形式,可以表示为字符串、段落、列表、表格或图片。

    每种元素都有自己的格式,例如,QTextBlockFormat类对应于QTextBlock类,QTextBlock类用于表示一块文本,通常可以理解为一个段落,但它并不仅指段落;QTextBlockFormat类则表示这一块文本的格式,如缩进的值、与四边的边距等。

    从上图可以看出用于表示编辑文本中的光标QTextCursor类是一个非常重要也经常会用到的类,它提供了对QTextDocument文档的修改接口,所有文档格式的修改说到底都与光标有关。例如,改变字符的格式,实际上是指改变光标处字符的格式。又例如,改变段落的格式,实际上是指改变光标所在段落上的格式。因此,所有对QTextDocument的修改都能通过QTextCursor类实现,QTextCursor类在文档编辑类程序中有着重要的作用。

4.1 设置字体

完成设置选定文字字体的函数ShowFontComboBox()代码如下:

</pre><pre name="code" class="cpp">void ImgProcessor::ShowFontComboBox(QString comboStr)   //设置字体
{    
    QTextCharFormat fmt;    
    fmt.setFontFamily(comboStr);    
    mergeFormat(fmt);     //将新的格式应用到光标选区内的字符
}

前面介绍过,所有对于QTextDocument进行的修改都通过QTextCursor类来完成,具体代码如下: 

void ImgProcessor::mergeFormat(QTextCharFormat format)
{    
    QTextCursor cursor =showWidget->text->textCursor();      //获得编辑框中的光标
    if(!cursor.hasSelection())          //若光标没有高亮选区则将光标所在处的词作为选区,由前后空格或“,”、”.“等标号区分词
    {        
        cursor.select(QTextCursor::WordUnderCursor);    
    }
     //调用QTextCursor的mergeCharFormat()函数将参数format所表示的格式应用到光标所在处的字符上
    cursor.mergeCharFormat(format); 
    //调用QTextEdit的mergeCurrentCharFormat()函数将格式应用到选区内所有的字符上
    showWidget->text->mergeCurrentCharFormat(format);
}

4.2 设置字号

设置选定文字字号大小的ShowSizeSpinBox()函数代码如下:

void ImgProcessor::ShowSizeSpinBox(QString spinValue)   //设置字号
{   
    QTextCharFormat fmt;   
    fmt.setFontPointSize(spinValue.toFloat());   
    showWidget->text->mergeCurrentCharFormat(fmt);
}

4.3 设置文字加粗

    文字的粗细值由QFont::Weight表示,它是一个整型值,取值范围是0-99,有五个预设值,分别为:QFont::Light(25)、QFont::Normal(50)、QFont::DEMIBold(63)、QFont::Bold(75)和QFont::Black(87),通常在QFont::Normal和QFont::Bold之间转换。

设置选定文字为加粗显示的ShowBoldBtn()函数代码如下:

void ImgProcessor::ShowBoldBtn()   //设置文字显示加粗
{    
    QTextCharFormat fmt;    
    fmt.setFontWeight(boldBtn->isChecked()?QFont::Bold:QFont::Normal);    
    showWidget->text->mergeCurrentCharFormat(fmt);
}

4.4 设置文字倾斜

设置选定文字为斜体显示的ShowItalicBtn()函数代码如下:

void ImgProcessor::ShowItalicBtn()   //设置文字显示斜体
{    
    QTextCharFormat fmt;    
    fmt.setFontItalic(italicBtn->isChecked());    
    showWidget->text->mergeCurrentCharFormat(fmt);
}

4.5 文字加下划线

在选定文字下方加下画线的ShowUnderlineBtn()函数代码如下:

void ImgProcessor::ShowUnderlineBtn()    //设置文字加下画线
{    
    QTextCharFormat fmt;    
    fmt.setFontUnderline(underlineBtn->isChecked());    
    showWidget->text->mergeCurrentCharFormat(fmt);
}

4.6 设置文字颜色

设置选定文字颜色的ShowColorBtn()函数代码如下:

void ImgProcessor::ShowColorBtn()   //设置文字颜色
{ 
    QColor color=QColorDialog::getColor(Qt::red,this);   
     if(color.isValid())    
    { 
        QTextCharFormat fmt;        
        fmt.setForeground(color);        
        showWidget->text->mergeCurrentCharFormat(fmt);    
    } 
}

    上面使用了标准颜色对话框QColorDialog类,第一个参数制订了选中的颜色,默认是白色,通过QColor::isValid()可以判断用户选择的颜色是否有效,若用户单击”取消“按钮,QColor::isValid()将返回false。第二个参数定义了彼岸准颜色对话框的父窗口。

4.7 设置字符格式

当光标所在处的字符格式发生变化时调用此槽函数,函数根据新的字符格式将工具栏上各个格式控件的显示更新。

void ImgProcessor::ShowCurrentFormatChanged(const QTextCharFormat &fmt)
{
    fontComboBox->setCurrentIndex(fontComboBox->findText(fmt .fontFamily()));   
    sizeComboBox->setCurrentIndex(sizeComboBox->findText( QString::number(fmt.fontPointSize())));  
    boldBtn->setChecked(fmt.font().bold());  
    italicBtn->setChecked(fmt.fontItalic());   
    underlineBtn->setChecked(fmt.fontUnderline());
}

5 Qt5排版功能

具体实现步骤如下。

(1)在头文件中添加“private:”变量:

    QLabel *listLabel;                                     //排序设置项
    QComboBox *listComboBox;
    QActionGroup *actGrp;
    QAction *leftAction;
    QAction *rightAction;
    QAction *centerAction;
    QAction *justifyAction;  
    
    QToolBar *listToolBar;                               //排序工具栏 

(2)在头文件中添加“protected slots:”变量: 

    void ShowList(int); 
    void ShowAlignment(QAction *act); 
    void ShowCursorPositionChanged();

(3)在相对应的构造函数中,在语句“setCentralWidget(showWidget);”与语句“createActions();”之间添加如下代码:

    //排序
    listLabel =new QLabel(tr("排序"));    
    listComboBox =new QComboBox;
    listComboBox->addItem("Standard");
    listComboBox->addItem("QTextListFormat::ListDisc");
    listComboBox->addItem("QTextListFormat::ListCircle");
    listComboBox->addItem("QTextListFormat::ListSquare");
    listComboBox->addItem("QTextListFormat::ListDecimal");
    listComboBox->addItem("QTextListFormat::ListLowerAlpha");
    listComboBox->addItem("QTextListFormat::ListUpperAlpha");
    listComboBox->addItem("QTextListFormat::ListLowerRoman");
    listComboBox->addItem("QTextListFormat::ListUpperRoman");

(4)在构造函数的最后部分添加相关的事件关联: 

    connect(listComboBox,SIGNAL(activated(int)),this,SLOT(ShowList(int))); 
    connect(showWidget->text->document(),SIGNAL(undoAvailable(bool)),redoAction,SLOT(setEnabled(bool))); 
    connect(showWidget->text->document(),SIGNAL(redoAvailable(bool)), redoAction,SLOT(setEnabled(bool)));  
    connect(showWidget->text,SIGNAL(cursorPositionChanged()), this,SLOT(ShowCursorPositionChanged()));   

(5)在相对应的工具栏createActions()函数中添加如下代码:

    //排序:左对齐、右对齐、居中和两端对齐
    actGrp =new QActionGroup(this);  
    
    leftAction =new QAction(QIcon("left.png"),"左对齐",actGrp);
    leftAction->setCheckable(true);  

    rightAction =new QAction(QIcon("right.png"),"右对齐",actGrp);
    rightAction->setCheckable(true);  

    centerAction =new QAction(QIcon("center.png"),"居中",actGrp);
    centerAction->setCheckable(true);

    justifyAction =new QAction(QIcon("justify.png"),"两端对齐",actGrp);
    justifyAction->setCheckable(true);  

    connect(actGrp,SIGNAL(triggered(QAction*)),this,SLOT(ShowAlignment (QAction*)));   

(6)在相对应的工具栏createToolBars()函数中添加如下代码:

    //排序工具条
    listToolBar =addToolBar("list");
    listToolBar->addWidget(listLabel);
    listToolBar->addWidget(listComboBox);
    listToolBar->addSeparator();
    listToolBar->addActions(actGrp->actions());   <span style="line-height: 1.5; widows: auto; font-family: 微软雅黑; background-color: inherit;">  </span>

5.1 实现段落对齐

完成对按下某个对齐按钮的响应用ShowAlignment()函数,根据比较判断触发的是哪个对齐按钮,调用QTextEdit的setAlignment函数可以实现当前段落的对齐调整。具体代码如下:

void ImgProcessor::ShowAlignment(QAction *act)
{    
    if(act==leftAction)        
        showWidget->text->setAlignment(Qt::AlignLeft);    
    if(act==rightAction)        
        showWidget->text->setAlignment(Qt::AlignRight);    
    if(act==centerAction)        
        showWidget->text->setAlignment(Qt::AlignCenter);    
    if(act==justifyAction)        
        showWidget->text->setAlignment(Qt::AlignJustify);
}

响应文本中光标位置处发生改变的信号的ShowCursorPositionChanged()函数代码如下:

void ImgProcessor::ShowCursorPositionChanged()
{    
    if(showWidget->text->alignment()==Qt::AlignLeft)        
        leftAction->setChecked(true);    
    if(showWidget->text->alignment()==Qt::AlignRight)        
        rightAction->setChecked(true);    
    if(showWidget->text->alignment()==Qt::AlignCenter)        
        centerAction->setChecked(true);    
    if(showWidget->text->alignment()==Qt::AlignJustify)        
        justifyAction->setChecked(true);
}

5.2 实现文本排序

    文本排序功能实现的基本流程如下:

    QTextListFormat包含两个基本属性,一个为QTextListFormat::style,表示文本采用哪种排序方式;另一个为QTextListFormat::indent,表示排序后的缩进值。

实现根据用户选择的不同排序方式对文本进行排序的ShowList()函数代码如下:

void ImgProcessor::ShowList(int index)
{    
    QTextCursor cursor=showWidget->text->textCursor();

    if(index!=0)
    {
        QTextListFormat::Style style=QTextListFormat::ListDisc;
        switch(index)                           //设置style属性值,Qt提供了下面8中文本排序方式
        {
        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;
        case 7:
            style=QTextListFormat::ListLowerRoman; break;  
        case 8:
            style=QTextListFormat::ListUpperRoman; 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 bfmt;
        bfmt.setObjectIndex(-1);
        cursor.mergeBlockFormat(bfmt);
    }
}

 

 

发布了48 篇原创文章 · 获赞 100 · 访问量 26万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章