Qt開發設置技巧

 

Qt在開發桌面客戶端方面有很多方面做的很好,功能很強大,在免費並能跨平臺的開發庫裏,做到了可以很好的滿足一般客戶端開發的需求。Qt庫不光在界面上,而且在XML解析,JSON數據解析,網絡通訊等各個功能點,都已經具備了好用的開發類庫。Qt尤其在圖形化處理方面有着自己很不一般的體驗,和功能。

 

        下面我結合我的開發經歷,對Qt的一些功能點和用法進行一些小結,希望給開發者提供一些有用的幫助,共同學習。

(一) 自定義窗口的開發。

我們在開發項目中,經常需要開發一個視覺設計人員給定好的窗口,我們用Qt開發這樣的窗口如圖:

 

        這樣一個完全自定義的窗口,是如果使用Qt做出來的呢?首先我們需要好的視覺設計師提供配色好看的圖片。作爲客戶端開發者來講,好的視覺樣式是給用戶的第一感覺。

下面我就簡述一下做一個這樣的qt窗口的步驟,

1首先創建一個QWidget

 

 

2、託拽上去你需要的控件,這就是所見即所得的好處。

3、主窗口設置屬性如下:

    setWindowFlags(Qt::FramelessWindowHint);//去掉邊框

    setAttribute(Qt::WA_TranslucentBackground,true); //背景透明

    setStyleSheet("QFrame{background: transparent; border: 0px solidwhite;}"); //背景透明

4、單個控件設置圖片:

ui.label_Logo->setPixmap(QPixmap(":/Test/image/VDiskLogo.ico"));

這裏的圖片可以是png bmp ico 等

":/Test/image/VDiskLogo.ico"是圖片的資源路徑,這裏給開發者詳細介紹下:

文件路徑是你建立的Qt工程中的.qrc文件裏你添加這個圖片文件之後拼出來的全路徑。

 

   還有一種方式就是Qt窗口樣式表 如下

    ui.label_Apply->setStyleSheet("QLabel{border-image:url(:/VdiskPCLit/image/setdlg/LitBt.png);border:1px}");

    這個也可以達到設置控件圖片以及樣式的目的,Qt的樣式表很強大,建議大家好好研究一下,可以爲很多控件進行美化。這裏不詳細介紹 Qss,待以後專門找一個章節去介紹。大家先對此方法有個印象。

5、重載窗口的幾個關鍵函數:

        void mousePressEvent(QMouseEvent *e);

    void mouseMoveEvent(QMouseEvent *e);

    void mouseReleaseEvent(QMouseEvent *e);

    void keyPressEvent ( QKeyEvent * event );

        void showEvent(QShowEvent *evt);

相信用過Qt的同學對這幾個Event已經比較熟悉,就不用我多介紹了。

這裏着重說下bool eventFilter(QObject *target, QEvent*event);

這個eventFilter 就是父窗口對子控件的相應,比如鼠標點擊,鼠標經過,鼠標釋放等。

bool eventFilter(QObject *target, QEvent*event)

    {

        if (target == ui.label_CheckUseDefaultPath)//這裏判斷是否是需要響應的控件

        {

             if(event->type() ==QEvent::MouseButtonPress)//控件相應類型

             {

                  

}

}

}

    這裏有個問題,大家可能也遇到過,MouseButtonPress沒有區分左鍵還是右鍵,這是Qt的一個Bug。

 

 

(二) 文件列表展示

我們做軟件,經常會使用列表展示一些信息,例如文件列表,任務列表,人員信息列表等等需求。

這裏介紹些Qt的列表控件:

QListView和QTreeView

這兩個控件像是一對孿生兄弟,因爲他們都繼承於QAbstractItemView這個類,但各有各的特性,這就歸功於面向對象的C++能讓世界變得豐富多彩~呵呵。這裏有點說多了,總之我們使用Qt的這兩個列表的時候,可以找到他們的共性,和各自的差異點。

        首先直觀的看一下,各自的特點

QTreeWidget

 

 

QTreeView

 

QListView

 

QListView不能加Header這個是我對 Qt比較鄙視的地方。List本來就應該有列頭,這裏Qt沒有做好,不知道以後的版本里面會不會加上。

而如果你需要帶Header的列表,必須使用QTreeView.這個類。

Qt 中View的數據都是用Model控制的,典型的MVC設計模式。這裏簡單介紹下Model/view的關係
在model/view構架中,model爲view和delegates使用數據提供了標準接口。在Qt中,標準接口QAbstractItemModel類中被定義。不管數據在底層以何種數據結構存儲,QAabstractItemModel的子類會以層次結構的形式來表示數據,結構中包含了數據項表。我們按這種約定來訪問model中的數據項,但這個約定不會對如何顯示這些數據有任何限制。數據發生改變時,model通過信號槽機制來通知關聯的views。

Model Indexes

爲了使數據存儲與數據訪問分開,引入了model index的概念。通過modelindex,可以引用model中的數據項,Views和delegates都使用indexes來訪問數據項,然後再顯示出來。因此,只有model需要了解如何獲取數據,被model管理的數據類型可以非常廣泛地被定義。Modelindexes包含一個指向創建它們的model的指針,這會在配合多個model工作時避免混亂。
QAbstractItemModel *model = index.model();

modelindexes提供了對一項數據信息的臨時引用,通過它可以訪問或是修改model中的數據。既然model有時會重新組織內部的數據結構,這時modelindexes便會失效,因此不應該保存臨時的modelindexes。假如需要一個對數據信息的長期的引用,那麼應該創建一個persistent modelindex。這個引用會保持更新。臨時的model indexes由QModelIndex提供,而具有持久能力的modelindexes則由QPersistentModelIndex提供。在獲取對應一個數據項的modelindex時,需要考慮有關於model的三個屬性:行數,列數,父項的model index。


行與列
在最基本的形式中,一個model可作爲一個簡單的表來訪問,每個數據項由行,列數來定位。這必不意味着
底層的數據用數組結構來存儲。行和列的使用僅僅是一種約定,它允許組件之間相互通訊。可以通過指定
model中的行列數來獲取任一項數據,可以得到與數據項一一對應的那個index。
QModelIndex index = model->index(row, column,...);
Model爲簡單的,單級的數據結構如list與tables提供了接口,它們如上面代碼所顯示的那樣,不再需要別的信息被提供。當我們在獲取一個modelindex時,我們需要提供另外的信息。

上圖代表一個基本的table model,它的每一項用一對行列數來定位。通過行列數,可以獲取代表一個數據項的modelindex .
QModelIndex indexA = model->index(0, 0,QModelIndex());
 QModelIndex indexB =model->index(1, 1, QModelIndex());
 QModelIndex indexC =model->index(2, 1, QModelIndex());
一個model的頂級項,由QModelIndex()取得,它們上式被用作父項。

父項
類似於表的接口在搭配使用table或list view時理想的,這種行列系統與view顯示的方式是確切匹配的。
然則,像tree views這種結構需要model提供更爲靈活的接口來訪問數據項。每個數據項可能是別的項的
父項,上級的項可以獲取下級項的列表。
當獲取model中數據項的index時,我們必須指定關於數據項的父項的信息。在model外部,引用一個數據
項的唯一方法就是通過model index,因此需要在求取model index時指定父項的信息。
QModelIndex index = model->index(row, column,parent);

上圖中,A項和C項作爲model中頂層的兄弟項:
 QModelIndex indexA =model->index(0, 0, QModelIndex());
 QModelIndex indexC =model->index(2, 1, QModelIndex());
A有許多孩子,它的一個孩子B用以下代碼獲取:
QModelIndex indexB = model->index(1, 0,indexA);

項角色
model中的項可以作爲各種角色來使用,這允許爲不同的環境提供不同的數據。舉例來說,Qt::DisplayRole被用於訪問一個字符串,它作爲文本會在view中顯示。典型地,每個數據項都可以爲許多不同的角色提供數據,標準的角色在Qt::ItemDataRole中定義。我們可以通過指定modelindex與角色來獲取我們需要的數據:
QVariant value = model->data(index, role);

角色指出了從model中引用哪種類型的數據。views可以用不同的形式顯示角色,因此爲每個角色提供正確
的信息是非常重要的。通過爲每個角色提供適當數據,model也爲views和delegates提供了暗示,如何正確地
把這些數據項顯給用戶。不同的views可以自由地解析或忽略這些數據信息,對於特殊的場合,也可以定義
一些附加的角色。
概念總結:
1,Model indexes爲views與delegages提供model中數據項定位的信息,它與底層的數據結構無關。
2,通過指定行,列數,父項的model index來引用數據項。
3,依照別的組件的要求,model indexes被model構建。
4,使用index()時,如果指定了有效的父項的model index,那麼返回得到的modelindex對應於父項的某個孩子。
5,使用index()時,如果指定了無效的父項的model index,那麼返回得到的modelindex對應於頂層項的某個孩子。
6, 角色對一個數據項包含的不同類型的數據給出了區分。

使用Model Indexes
QDirModel *model = new QDirModel;
    QModelIndex parentIndex =model->index(QDir::currentPath());
    int numRows = model->rowCount(parentIndex);
 for (int row = 0; row < numRows;++row)
 {
        QModelIndex index = model->index(row, 0,parentIndex);
        tring text = model->data(index,Qt::DisplayRole).toString();
        // Display the text in a widget.

    }
以上的例子說明了從model中獲取數據的基本原則:
1,model的尺寸可以從rowCount()與columnCount()中得出。這些函數通常都需要一個表示父項的modelindex。
2,model indexes用來從model中訪問數據項,數據項用行,列,父項model index定位。
3, 爲了訪問model頂層項,可以使用QModelIndex()指定。
4, 數據項爲不同的角色提供不同的數據。爲了獲取數據,除了model index之外,還要指定角色。

這次對界面的使用上介紹的比較多,Qt的博大精深有很多需要去總結,以後對Qss等進行一些更詳細的介紹,還有QXML等衆多好用的功能。如果發現本人有對Qt總結不對的地方,請指正。

轉自原文章地址

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