佛山做網(wǎng)站百度app免費下載
一、可能遇到的一些問題
Q1:如何禁用拖動?
在TableView下加一句代碼即可:
interactive: false
補充:這個屬性并不專屬于TableView,而是一個通用屬性。很多Controls下的控件都可以使用,其主要作用就是控制交互的。
舉個例子:像width、height、color這些都屬于通用屬性,并不是說只有一個控件需要指定它的寬高、顏色。這種通用特性在QML是非常常見的。
或許你想給某個控件實現(xiàn)某種功能,沒準這個功能其實就是其他控件中的一個屬性罷了。
Q2:設(shè)置了標題欄之后,程序直接卡死?
可能是Layout布局的問題,把Layout布局換成Item試試。
Q3:表頭數(shù)據(jù)和內(nèi)容數(shù)據(jù)重疊顯示了?或者一片空白?
大概率還是布局的問題,檢查一下吧!
補充:在 HorizontalHeaderView 中使用了 syncView 屬性,就相當于是將 HorizontalHeaderView 和指定的 TableView 綁定了,它默認會有個布局,就是把水平標題欄放在表格內(nèi)容的上方,但是左右的對齊方式可能并不是我們想要的,所以在做整體布局時需要注意這一點。
還有其它問題?
上面的幾個問題是我在做這個實例的時候遇到的,如果你有別的問題可以在評論區(qū)留言,我會逐一回復(fù)哦~
二、QML TableView 實例演示
下面截圖中的紅框部分就是最終的效果,雖然看似簡陋,實際確實有點簡陋。。。。
好消息是,這個只是我用來演示給大家看的,并不是我個人審美就這樣。。。。所以,等大家學會了怎么去用 TableView 這個控件,就按照自己的想法和需求去設(shè)計它吧!
實現(xiàn)步驟1:TableModel
在QML中,像TableView、ListView這種控件,視圖(View)和數(shù)據(jù)(model)都是分開的。所以我們需要依次去完善他們。
那么,先來實現(xiàn)一個model吧!
//表頭數(shù)據(jù)放TableModelColumn里,內(nèi)容數(shù)據(jù)放rows里,由TableModel統(tǒng)一管理TableModel{id: tablemodel_2TableModelColumn { display: "狀態(tài)" } //后面表頭會用到TableModelColumn { display: "簡稱" }TableModelColumn { display: "售價" }TableModelColumn { display: "庫存" }rows: //表格里具體顯示的內(nèi)容[{"狀態(tài)": true,"簡稱": "AK-74自動步槍","售價": 149,"庫存": 500},{"狀態(tài)": true,"簡稱": "81式自動步槍","售價": 199,"庫存": 300},{"狀態(tài)": true,"簡稱": "M16突擊步槍","售價": 119,"庫存": 100},{"狀態(tài)": true,"簡稱": "SCAR突擊步槍","售價": 129,"庫存": 100},{"狀態(tài)": true,"簡稱": "HKG36突擊步槍","售價": 159,"庫存": 100}]}
在上面的代碼片段中,最外層是1個TableModel,這個TableModel和TableView是同級的,不是寫在TableView下面的哈,文章最后我會把完整的代碼也發(fā)出來。
我們這個TableModel定義1個id叫tablemodel_2,因為等會后面需要通過id來調(diào)用這個TableModel里面的數(shù)據(jù)。
接著,我們連續(xù)寫了4行TableModelColumn,這個是后面要用到的水平標題欄的數(shù)據(jù),每一個TableModelColumn就代表1列。
最后是1個 rows,這個rows后面緊跟的一個是列表[ ],列表里面放的就是除表頭以外的數(shù)據(jù)了。形式就是花括號里一對對的鍵和值,而鍵就是上面TableModelColumn中的文本,也就是列名,值才是每個單元格中具體要顯示出來的數(shù)據(jù)。
然后你可能會想到,哎呀~這么多行代碼下去,實際就顯示5行數(shù)據(jù),如果列很多、數(shù)據(jù)成千上萬,這代碼得寫多長啊!
這點不用擔心啦!因為QML的專家早就考慮到了。如果數(shù)據(jù)量很少,而且是固定的,model直接寫出來就行了。如果數(shù)據(jù)多,那最好用C++的模型類來提供。需要注意的是:C++模型必須是QAbstractItemModel的子類。
這個C++的模型類有點復(fù)雜,后面我會專門寫一篇文章來介紹它。
實現(xiàn)步驟2:TableView
做完數(shù)據(jù)層(model),下面我們就來做具體的外觀(View)吧!請看下面代碼:
?View層,大概分為2個部分,藍色框框里是一些整體的屬性設(shè)置,綠色框框里是針對每一列數(shù)據(jù)的顯示細節(jié)的描述。
在delegate中,我們寫了4個DelegateChoice。一共是5行數(shù)據(jù),為什么我們只寫了4個?因為如果你只是簡單的顯示model里的數(shù)據(jù)、不會有交互,那么就統(tǒng)一用一個DelegateChoice就行啦!
什么叫不會有交互?你看前面截圖中第一列的數(shù)據(jù)是不是都是復(fù)選框?復(fù)選框是干嘛的?不就是給用戶去勾選、去交互的嘛~
所以像這種后期會交互的數(shù)據(jù)列,就要單獨的DelegateChoice去寫。我展開第一個DelegateChoice中的代碼給你看一下:
DelegateChoice {column: 0 //指定哪一列可編輯delegate: Rectangle{implicitWidth: 150implicitHeight: 40color: t_tableView_2.currentRow === row ? "#c8e5b3" : "#eeeeee"CheckBox{anchors.verticalCenter: parent.verticalCenteranchors.left: parent.leftchecked: model.display //CheckBox的默認狀態(tài)就是模型里的值onToggled: model.display = checked //編輯即更新數(shù)據(jù)到模型Material.accent: "green"}}}
看到了嗎?里面竟然還有一個delegate?這個最里層的delegate就是設(shè)置具體的單元格的顯示方式啦!
可能有了解ListView的小伙伴好奇了,我之前做ListView的時候只需要1個delegate就行了,怎么這個TableView還要套2層delegate,外面竟然還有個什么DelegateChoice?這個DelegateChoice又是什么?干啥用的?
這個DelegateChoice是按列去設(shè)置的,每一列都有不同的情況和需求,如果我們這個表格是涉及到交互、而不單單是給用戶看看的,那就需要用DelegateChoice對具體的列去設(shè)置,因為可能第1列全部是復(fù)選框,第3列又全都是單行輸入框,怎么都得去單獨設(shè)置~
實現(xiàn)步驟3:HorizontalHeaderView
這個HorizontalHeaderView就是水平標題欄啦!
HorizontalHeaderView {id: horizontalHeaderViewsyncView: t_tableView_2interactive: false //禁用拖動delegate: Rectangle {implicitWidth: 150; implicitHeight: 40; color: "transparent"Text {text: tablemodel_2.columns[index].displayfont.bold: trueanchors.verticalCenter: parent.verticalCenteranchors.left: parent.leftanchors.leftMargin: 10}}}
這個水平標題欄和TableView也是同級的,不要寫到TableView里面去嘍!
在QML中,標題欄和表格是分開設(shè)置的,所以設(shè)置了標題欄之后需要通過syncView屬性去綁定具體的TableView。
然后這個水平標題欄也是默認有交互效果的,如果你不想讓它動,就也用interactive屬性禁用吧!
完整代碼
import QtQuick
import QtQuick.Controls.Material
import QtQuick.Controls
import QtQuick.Layouts
import Qt.labs.qmlmodels //TableModel需要用到的庫Item {//表頭數(shù)據(jù)放TableModelColumn里,內(nèi)容數(shù)據(jù)放rows里,由TableModel統(tǒng)一管理TableModel{id: tablemodel_2TableModelColumn { display: "狀態(tài)" } //后面表頭會用到TableModelColumn { display: "簡稱" }TableModelColumn { display: "售價" }TableModelColumn { display: "庫存" }rows: //表格里具體顯示的內(nèi)容[{"狀態(tài)": true,"簡稱": "AK-74自動步槍","售價": 149,"庫存": 500},{"狀態(tài)": true,"簡稱": "81式自動步槍","售價": 199,"庫存": 300},{"狀態(tài)": true,"簡稱": "M16突擊步槍","售價": 119,"庫存": 100},{"狀態(tài)": true,"簡稱": "SCAR突擊步槍","售價": 129,"庫存": 100},{"狀態(tài)": true,"簡稱": "HKG36突擊步槍","售價": 159,"庫存": 100}]}TableView{id: t_tableView_2width: contentWidthheight: contentHeightanchors.top: horizontalHeaderView.bottominteractive: false //禁止拖動rowSpacing: 1 //行間距。列間距是columnSpacingmodel: tablemodel_2//行選擇,選中事件的處理selectionModel: ItemSelectionModel {}//指定可編輯的列,把CheckBox控件放進表格中delegate: DelegateChooser {DelegateChoice {column: 0 //指定哪一列可編輯delegate: Rectangle{implicitWidth: 150implicitHeight: 40color: t_tableView_2.currentRow === row ? "#c8e5b3" : "#eeeeee"CheckBox{anchors.verticalCenter: parent.verticalCenteranchors.left: parent.leftchecked: model.display //CheckBox的默認狀態(tài)就是模型里的值onToggled: model.display = checked //編輯即更新數(shù)據(jù)到模型Material.accent: "green"}}}DelegateChoice {column: 2delegate: Rectangle{implicitWidth: 150implicitHeight: 40color: t_tableView_2.currentRow === row ? "#c8e5b3" : "#eeeeee"BasicTextField{anchors.verticalCenter: parent.verticalCenteranchors.left: parent.leftanchors.leftMargin: 10width: 80; height: 30text: model.displayonAccepted: model.display = text //回車更新數(shù)據(jù)onEditingFinished: model.display = text //焦點改變更新數(shù)據(jù)}}}DelegateChoice {column: 3delegate: Rectangle{implicitWidth: 150; implicitHeight: 40color: t_tableView_2.currentRow === row ? "#c8e5b3" : "#eeeeee"BasicTextField{anchors.verticalCenter: parent.verticalCenteranchors.left: parent.leftanchors.leftMargin: 10width: 80; height: 30text: model.displayonAccepted: model.display = text //回車更新數(shù)據(jù)onEditingFinished: model.display = text //焦點改變更新數(shù)據(jù)}}}DelegateChoice //默認顯示方式,不指定具體列{delegate: Rectangle{implicitWidth: 150; implicitHeight: 40//選中行變色(生效前提是:為selectionModel分配一個ItemSelectionModel)color: t_tableView_2.currentRow === row ? "#c8e5b3" : "#eeeeee"Text{text: displayanchors.verticalCenter: parent.verticalCenteranchors.left: parent.leftanchors.leftMargin: 10}}}}}HorizontalHeaderView {id: horizontalHeaderViewsyncView: t_tableView_2interactive: false //禁用拖動delegate: Rectangle {implicitWidth: 150; implicitHeight: 40; color: "transparent"Text {text: tablemodel_2.columns[index].displayfont.bold: trueanchors.verticalCenter: parent.verticalCenteranchors.left: parent.leftanchors.leftMargin: 10}}}
}