用Qt寫軟件系列五:一個安全防護軟件的製作(2)

引言

       在上一篇中講述了主窗體的創建和設計。主窗體的無邊框效果、陰影效果、拖動事件處理、窗體美化等工作在前面的博客中早就涉及,因此上篇博文中並未花費過多筆墨。這一篇繼續講述工具箱(Tool Button)的實現。另外,在實現的過程中還做了另外一個貼心的小功能:可伸縮的側邊欄。不過後來發現應用起來後效果不佳,於是就沒在主窗體中加入這個功能了,單獨做了一個demo作爲示範。

工具箱的實現

       工具箱是將若干的工具按鈕組織在一起,爲用戶提供簡便導航功能的一個組件。在Qt中實現這個功能不難,Qt庫本身就提供了QToolButton和QToolBox兩個類用於類似功能。在這裏我們從QToolButton類派生一個子類自定義按鈕動作。QToolButton類本身只提供了一些基本功能。因此我們需要實現一些事件處理器來自定義工具按鈕的動作和外觀。

       看碼說話:

   在該子類中我們重寫了enterEvent(),leaveEvent(), paintEvent(), mousePressEvent()這幾個事件處理函數。分別對應鼠標進入、離開、點擊按鈕區域事件,paintEvent()則用於繪製按鈕的外觀。此外,還是用了幾個狀態變量,用於記錄鼠標當前的移動狀態。利用這些狀態,我們就能順利實現不同狀態的外觀繪製。值得注意的是doPaintStuff()這個函數。這個函數實際做的工作是給工具按鈕添加垂直的漸變效果。使用了QLinearGradient這個類,可以實現線性的漸變效果,這在很多界面元素設計中都非常有用。

       在主函數中怎麼調用這個自定義的按鈕類呢?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
MainWin::MainWin(QWidget *parent)
    : QWidget(parent)
{
    ui.setupUi(this);
     
    setWindowTitle("Tool Button");
    QStringList string_list;
    string_list<<":/toolWidget/tiJian"<<":/toolWidget/muMa"<<":/toolWidget/repair"<<":/toolWidget/qingLi"
        <<":/toolWidget/jiaSu"<<":/toolWidget/expert"<<":/toolWidget/menZhen"<<":/toolWidget/gongNeng";
 
    QVBoxLayout *layout = new QVBoxLayout(this);
    QHBoxLayout *button_layout = new QHBoxLayout(this);
 
    QSignalMapper *signal_mapper = new QSignalMapper(this);
    for(int i=0; i< string_list.size(); i++)
    {
        CustomToolButton *tool_button = new CustomToolButton(string_list.at(i));
        tool_button->setText("Test");
        button_list.append(tool_button);
        connect(tool_button, SIGNAL(clicked()), signal_mapper, SLOT(map()));
        signal_mapper->setMapping(tool_button, QString::number(i, 10));
 
        button_layout->addWidget(tool_button, 0, Qt::AlignBottom);
    }
    layout->addLayout(button_layout);
    layout->addStretch();
    setLayout(layout);
 
}

   從代碼中看,我們用了一個循環生成了若干個自定義按鈕,然後全部放到水平佈局管理器中進行管理。這個很容易理解,重點內容是QSignalMapper類的應用。QSignalMapper類是一個工具類,它主要的功能是將一組無參數信號集中管理,將信號用整型值或字符串值表示,然後再以一種統一的形式發送出去。其好處是,當有很多的信號需要統一管理的時候非常方便,不用手動調用connect()爲信號綁定槽函數,因此代碼結構也更爲簡練。在上面的代碼中,我們將按鈕點擊信號轉換爲數值形式表示。這樣也是很自然的做法,一方面形式簡單,另一方面水平排列的工具按鈕按序編號符合人類習慣。

可伸縮的側邊欄

       還是看看什麼叫做可伸縮的側邊欄,這樣的功能在QQ的聊天窗口就可以看見:

       側邊欄的收縮可以在需要的時候隱藏部分組件,從而爲其他組件提供更爲廣闊的視角。如上圖中的側邊欄收縮爲文本框組件提供更多的空間,整個界面上看起來也更爲清爽。稍微一剖析:這個邊欄要能點擊,點擊之後要切換圖標,響應的組件要隱藏。如此一分析,代碼可如下編寫:

  

       可以發現這裏的側邊欄果然一直固定在最左側,要達到QQ聊天界面那要的效果呢,只需要改幾行代碼就好了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
TestSideBar::TestSideBar(QWidget *parent)
    : QMainWindow(parent)
{
        // 其他保持不變,省略……
 
    mainSplitter->addWidget(leftWidget);
    mainSplitter->addWidget(zoomButton);
    mainSplitter->addWidget(rightWidget);
 
    mainLayout->addWidget(mainSplitter, 1);
    mainLayout->setSpacing(0);
    mainLayout->setContentsMargins(0, 0, 0, 0);
 
        // 其他保持不變,省略……
}

  

小結

       這一篇主要講了上篇遺留的一個功能,工具按鈕組的開發。另外,實現了另外一個功能:側邊欄的伸縮。下一篇繼續樹形控件(tree widget)、堆棧式窗口布局(stacked layout)的講解。

 

轉載自:http://www.cnblogs.com/csuftzzk/p/Trojan_Assessment_Platform_2.html

發佈了2 篇原創文章 · 獲贊 5 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章