Qml之自編表格控制元件(動態)?

筆者在使用qt的qml語言開發產品時候,經常需要用到一些表格類的控制元件,用來合理有序地顯示內容。畢竟沒有表格規限內容,會看起來很亂。筆者使用的是qt4.8版本的qml,所以qml沒有關於表格類的控制元件。這就有點頭痛了,沒辦法,只能親自寫一個表格控制元件出來。

這一表格控制元件採用最基本qml元素編寫,相容性非常好,該表格控制元件還支援qt介面呼叫,動態顯示。在文章的最後會公開原始碼,僅供讀者們參考學習。

Qml之自編表格控制元件(動態)

工具/原料

linux或windows系統

qt4.8版本以上

方法/步驟

1. 這個表格控制元件是這樣使用的,表格控制元件分為兩個部分,一部分是標題欄,另一部分則為內容。為了使得表格控制元件區分明朗,我們需要設定ChartTitleBar控制元件(標題欄)和ChartBar控制元件(內容欄)。

Qml之自編表格控制元件(動態)

1. 這裡的兩個子控制元件的屬性也有點不一樣,但有些屬性是一樣的。

① 它們都需要設定高度,ChartTitleBar的高度則是標題欄的高度,而ChartBar的高度則是內容欄的高度;

② 但有一個高度需要設定,那就是內容欄的每一行的高度引數屬性為selectedHeight。至於顏色就是它們的背景色了,預設是白色的;

③ 標題欄當然需要設定標題,設定標題使用arrayTitle引數,它是陣列型資料;

④ 標題欄與內容欄的每一列都是需要寬度的,而寬度的設定則由這一引數實現selectedWidth,這一個引數有點意思的,可以實現指定寬度。

比如有10列每列都是50的寬度,這它的表示為:[“1-10”, 50]。解釋一下”1-10”指的是1到10列,而50為寬度;有些讀者會問,我不要等分的寬度,我要指定的,這也是可以得。

再打一個比如,標題欄有10列,1到5列寬度20,6-8列寬度50,9-10列寬度80。那麼它應該這樣表示[[“1-5”, 20], [“6-8”, 50], [“9-10”, 80]]。

相信看完這兩個例子對這些引數有理解了吧。

⑤ 還有一個屬性就是modelSomeData,它的作用是內容的提供者,而arrayName屬性與modelSomeData的內容標識是相對應的。

Qml之自編表格控制元件(動態)

3. 接著就是原始碼分析了。

ChartTitleBar控制元件在ChartTitleBar.qml裡面,圖片顯示程式碼有限我就抽取最核心的程式碼講解。

① 這裡使用ListView控制元件構成標題欄,為什麼使用這一個控制元件呢?關於佈局的可以使用Row水平佈局,但是這是一個動態的標題欄,Row是程式執行的時候就必須要限定列的大小;

② 而String(arrayTitle[index])引數就是讀取標題的每一列內容;

③ Component.onCompleted:這個建構函式除了設定行的寬度,還有一個小作用就是使用listView.model.append()來設定列的多少;

④ 在圖片的底部有一個count()函式,筆者認為這裡是寫得不錯的地方,運用的只是也是比較多。請允許我一一道來哈。count()函式呼叫了一個stringToInt函式該函式作用是將字串轉換為整型。substring()函式則為擷取指定字元,indexOf()函式則為匹配到合適字元返回當前位置。

這個那麼長的表示式有什麼用呢?

舉個例子: 假如selectedWidth[i][0]等於字串”1-10”, 那麼

selectedWidth[i][0].substring(selectedWidth[i][0].indexOf('-')+1, selectedWidth[i][0].length)就會等於10,而stringToInt(selectedWidth[i][0].substring(0, selectedWidth[i][0].indexOf('-')))就會等於1,它們的作用就是返回列數的。

Qml之自編表格控制元件(動態)

4. 原始碼分析內容顯示控制元件ChartBar

① 內容顯示控制元件的原理與標題欄控制元件原理差不多,這裡抽取核心程式碼講解;

② 它們的構成是一個大ListView組成的,而一個大的ListView就是顯示所有內容了,而所有內容裡面又包含著每一行,而每一行作為一個獨立的ListView又供顯示內容,即ChartBar控制元件又兩個ListView組成;

③ 其實這一控制元件也是呼叫了ChartTitleBar控制元件了,我們換個思路去想,內容的標題就是內容了,當然要重用控制元件啦;

Qml之自編表格控制元件(動態)

5.控制元件ChartBar也是有精妙的地方的,這裡這種講解,就是filterArray(index)函式。

① 這一個函式傳入的是delegate屬性的index這個屬性必須傳入,否則無法工作,作用則是控制get()的值;

② arrayName.length是讀陣列長度,進行arrayName的過濾;

③ 使用listView.model.get(index-1)[String(arrayName[i])]需要特別特別注意,就是get(index-1),這個因為index是從1計數的,而get()函式是從0有效的,所以要相應地減1;

④ 為什麼不直接返回arrayName呢?

因為這裡存在一個賦值的問題。這裡對property variant arrayName: []這樣的陣列型數是不能直接使用下標寫入的,只能讀取。arrayName[1] = 1,這樣是錯誤的。

⑤ 怎樣才能正確寫入呢?

使用var array = []這樣的變數,array[0] = 1; array[1] = 2。這樣是對的因為型別是var,這是隻能在js裡面操作,然後這樣賦值arrayName = array。

Qml之自編表格控制元件(動態)

6. 檔案一覽與原始碼下載

原始碼下載:

Qml之自編表格控制元件(動態)

注意事項

1.使用get()如果傳入的是index則需要減1;

2. ChartTitleBar與ChartBar共同組成表格控制元件。

表格, 內容, 動態, 筆者, 控制元件,
相關問題答案