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萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章