研究了2天時間,網上連個例子都沒找到。這幾天都失眠了!也沒有大神指點下。。。我不想作這個了後端
list自帶title效果,所以。若是想實現帶title的網格佈局時,只能仿照安卓的思路,listview嵌套gridview數組
代碼以下:網絡
import QtQuick 2.9 import QtQuick.Window 2.2 import QtQuick.Layouts 1.3 import QtQuick.Controls 2.3 Window { visible: true width: 1280 height: 720 title: qsTr("Hello World") property var fenlei_texts: [ ["KTV熱歌","網絡歌曲","現場音樂","背景音樂","經典","情歌"], ["夜店","學習工做","咖啡館","運動","睡前","旅行"], ["傷感","安靜","快樂","勵志","治癒","思念"], ["00年代","90年代","80年代","70年代"], ["流行","電子","輕音樂","民謠","輕音樂","民謠","說唱","搖滾"], ["英語","韓語","日語","國語"] ] ListModel{ id: phoneModel } Component{ id: sectionHeader Rectangle{ width: parent.width height: childrenRect.height color: "lightsteelblue" Text{ text: section font.bold: true font.pointSize: 20 } } }//sectionHeader is end Component{ id:lisview_gridview Rectangle{ width: ListView.view.width height: 80 color: ListView.isCurrentItem?"#157efb":"#53d769" //選中顏色設置 border.color: Qt.lighter(color, 1.1) GridView{ id:grid_view model:fenlei_texts[index%6] height:parent.height width:parent.width
flickDeceleration:0
interactive:false
delegate: Component{ Rectangle{ id:back color:GridView.isCurrentItem?"yellow":"red" //選中顏色設置 height:80 width:80 Text{ anchors.centerIn: parent text:modelData } MouseArea { anchors.fill: parent acceptedButtons: Qt.AllButtons onClicked:{ grid_view.currentIndex = index //實現item切換 console.log("*******grid_currentIndex**********"+index) } onPressed: {back.color = "yellow"} onReleased: {back.color = "red"} } } } Component.onCompleted: { grid_view.currentIndex = -1; } } MouseArea { anchors.fill: parent propagateComposedEvents: true onPressed:{ listview.currentIndex = index //實現item切換 grid_view.currentIndex = -1 mouse.accepted = false console.log("*******List_currentIndex**********"+index) } } } } ListView { id:listview width: parent.width height: parent.height model:phoneModel clip:true delegate:lisview_gridview section.property: "manufacture" section.criteria: ViewSection.FullString section.delegate: sectionHeader } Component.onCompleted: { phoneModel.append({"manufacture":"主題"}) phoneModel.append({"manufacture":"場景"}) phoneModel.append({"manufacture":"心情"}) phoneModel.append({"manufacture":"年代"}) phoneModel.append({"manufacture":"流派"}) phoneModel.append({"manufacture":"語種"}) } }
鼠標穿透是qml永遠繞不過的梗呀!我差點都放棄了。app
總共有幾個難點:佈局
1)首先是佈局,動態加載的數據-model,使得後臺可以出現直接加載成model,對view進行數據的賦值學習
2)主題,場景,心情,年代,流派,語種是listview字體
而主題下的分類倒是gridview,怎麼區分一橫一縱的索引,以二維數組的形式得到。把得到索引,傳給後臺。後端可以根據索引,取得id,從而繼續請求數據ui
3)鼠標穿透,因爲qml本身的坑,多重mousearea,致使下層的mousearea永遠沒法響應pressed事件,那麼小分類就沒有點擊態。從用戶的效果,就不知道點擊了沒有。spa
當MouseArea響應事件順序都是press>release>click3d
仍然未解決問題:
1)Gridview,listview具備滑動效果,對於體驗不太好。
2)若是光標在一瞬間離開Gridview或者Listview,button的壓下態沒法復原。這個是QT共同問題。
效果圖:
import QtQuick 2.0 import QtQuick.Controls 2.3 Item { id:layout_recommend_list width: 1280 height: 720 visible: true property var fenlei_texts: [ ["KTV熱歌","網絡歌曲","現場音樂","背景音樂","經典","情歌"], ["夜店","學習工做","咖啡館","運動","睡前","旅行","夜店"], ["傷感","安靜","快樂","勵志","治癒"], ["00年代","90年代","80年代","70年代","思念"], ["流行","電子","輕音樂","民謠","輕音樂","民謠","說唱","搖滾"], ["英語","韓語","日語","國語"] ] Image{ id:back_img source: "images/background/bg_music.png" visible:true } MouseArea{ anchors.fill:parent enabled:true onClicked: {} onPressed: {} onReleased: {} } Item{ id:item_song_sheet visible:true Item{ x:14 y:73 width: 158 height: 50 Image{ id: img_return source:"images/button/btn_return/btn_return_n.png" } Text{ x:55 width: 103 height: parent.height verticalAlignment: Text.AlignVCenter horizontalAlignment: Text.AlignLeft text: qsTr("所有分類") font.pixelSize: 26 font.family: "FZLTHJW--GB1-0" color: "#ffffff" } MouseArea{ anchors.fill: parent onClicked: { if (stack.depth === 1) { stack.clear(); } else { stack.pop(); } } onPressed: { img_return.source = "images/button/btn_return/btn_return_p.png" } onReleased: { img_return.source = "images/button/btn_return/btn_return_n.png" } } } } ListModel{ id: phoneModel } Component{ id: sectionHeader Rectangle{ width: parent.width height: 66 color: "transparent" Rectangle{height:27;width:4;color: "#3cecc8"} Text{ anchors.left:parent.left anchors.leftMargin: 19 anchors.top:parent.top text: section font.pixelSize: 26 color: "#ffffff" font.family: "FZLTHJW--GB1-0" //字體 opacity: 0.9 } } }//sectionHeader is end function calculate_height(count) { console.log("*******count:**********",count) var divisor_count; var remainder_count; var divisor_height; var n divisor_count = Math.floor(count/4); remainder_count = count%4; if(divisor_count === 0) {n =1} else if(divisor_count >= 1) { if(remainder_count === 0) { n = divisor_count; } else { n = divisor_count + 1; } } console.log("*******n:**********",n) divisor_height = 152 + (n -1)*140; console.log("*******divisor_height:**********",divisor_height) return divisor_height; } Component{ id:lisview_gridview Rectangle{ width: ListView.view.width height: calculate_height(fenlei_texts[index%6].length) color: "transparent" border.color: Qt.lighter(color, 1.1) GridView{ id:grid_view property int spacing: 40 model:fenlei_texts[index%6] height:parent.height width:1280 cellWidth: 300 cellHeight: 140 contentWidth: 0 contentHeight:0 interactive:false delegate: Component{ Rectangle{ id:back color: "#31354d" width: {grid_view.cellWidth - grid_view.spacing} height: {grid_view.cellHeight - grid_view.spacing} Text{ anchors.centerIn: parent text:modelData font.pixelSize: 26 color: "#ffffff" font.family: "FZLTHJW--GB1-0" //字體 opacity: 0.9 } MouseArea { anchors.fill: parent acceptedButtons: Qt.AllButtons onClicked:{ grid_view.currentIndex = index //實現item切換 console.log("*******grid_currentIndex**********"+index) } onPressed: {back.opacity = 0.3} onReleased: {back.opacity = 1} } } } Component.onCompleted: { grid_view.currentIndex = -1; } } MouseArea { anchors.fill: parent propagateComposedEvents: true onPressed:{ listview.currentIndex = index //實現item切換 grid_view.currentIndex = -1 mouse.accepted = false console.log("*******List_currentIndex**********"+index) } } } } ListView { id:listview x:60 y:152 width: parent.width height: 466 model:phoneModel delegate:lisview_gridview section.property: "manufacture" section.criteria: ViewSection.FullString section.delegate: sectionHeader clip: true } Component.onCompleted: { phoneModel.append({"manufacture":"主題"}) phoneModel.append({"manufacture":"場景"}) phoneModel.append({"manufacture":"心情"}) phoneModel.append({"manufacture":"年代"}) phoneModel.append({"manufacture":"流派"}) phoneModel.append({"manufacture":"語種"}) } }
1)Gridview,listview具備滑動效果,對於體驗不太好。-->此問題解決 ,將Gridview的interactive置爲false.
若是有剪切效果,就把clip:true
若是是從後臺給的數據的話,想要動態實現二維數據,須要使用運用js拼出數據。如今須要的數據是數組套數組。好比tarray[onearray[],twoarray[],threearrap[]].
import QtQuick 2.0 import QtQuick.Controls 2.3 Item { id:layout_recommend_list width: 1280 height: 720 visible: true property int i: 0 Component.onCompleted: { console.log("*****complete********") qml_log_observer.request_info() } property var fenlei_texts:new Array Image{ id:back_img source: "images/background/bg_music.png" visible:true } Connections{ target: qml_log_observer onCategories_titles_changed:{ for(i = 0;i < titles.length;++i) { console.log("*****receive_Categories********") phoneModel.append({"manufacture":titles[i]}) } } onSubject_category_changed:{ console.log("*****receive********") fenlei_texts[0] = new Array(); for(var j=0;j<subject_category.length;j++){ fenlei_texts[0][j]=subject_category[j]; } } onScene_category_changed:{ console.log("*****receive********") fenlei_texts[1] = new Array(); for(var j=0;j<scene_category.length;j++){ fenlei_texts[1][j]=scene_category[j]; } } onMood_category_changed:{ console.log("*****receive********") fenlei_texts[2] = new Array(); //聲明二維,每個一維數組裏面的一個元素都是一個數組; for(var j=0;j<mood_category.length;j++){ //一維數組裏面每一個元素數組能夠包含的數量p,p也是一個變量; fenlei_texts[2][j]=mood_category[j]; //這裏將變量初始化,我這邊統一初始化爲空,後面在用所需的值覆蓋裏面的值 } } onAge_category_changed:{ console.log("*****receive********") fenlei_texts[3] = new Array(); //聲明二維,每個一維數組裏面的一個元素都是一個數組; for(var j=0;j<age_category.length;j++){ //一維數組裏面每一個元素數組能夠包含的數量p,p也是一個變量; fenlei_texts[3][j]=age_category[j]; //這裏將變量初始化,我這邊統一初始化爲空,後面在用所需的值覆蓋裏面的值 } } onGenre_category_changed:{ console.log("*****receive********") fenlei_texts[4] = new Array(); //聲明二維,每個一維數組裏面的一個元素都是一個數組; for(var j=0;j<genre_category.length;j++){ //一維數組裏面每一個元素數組能夠包含的數量p,p也是一個變量; fenlei_texts[4][j]=genre_category[j]; //這裏將變量初始化,我這邊統一初始化爲空,後面在用所需的值覆蓋裏面的值 } } onLanguage_category_changed:{ console.log("*****receive********") fenlei_texts[5] = new Array(); //聲明二維,每個一維數組裏面的一個元素都是一個數組; for(var j=0;j<language_category.length;j++){ //一維數組裏面每一個元素數組能夠包含的數量p,p也是一個變量; fenlei_texts[5][j]=language_category[j]; //這裏將變量初始化,我這邊統一初始化爲空,後面在用所需的值覆蓋裏面的值 } } } MouseArea{ anchors.fill:parent enabled:true onClicked: {} onPressed: {} onReleased: {} } Item{ id:item_song_sheet visible:true Item{ x:14 y:73 width: 158 height: 50 Image{ id: img_return source:"images/button/btn_return/btn_return_n.png" } Text{ x:55 width: 103 height: parent.height verticalAlignment: Text.AlignVCenter horizontalAlignment: Text.AlignLeft text: qsTr("所有分類") font.pixelSize: 26 font.family: "FZLTHJW--GB1-0" color: "#ffffff" } MouseArea{ anchors.fill: parent onClicked: { if (stack.depth === 1) { stack.clear(); } else { stack.pop(); } } onPressed: { img_return.source = "images/button/btn_return/btn_return_p.png" } onReleased: { img_return.source = "images/button/btn_return/btn_return_n.png" } } } } ListModel{ id: phoneModel } Component{ id: sectionHeader Rectangle{ width: parent.width height: 66 color: "transparent" Rectangle{height:27;width:4;color: "#3cecc8"} Text{ anchors.left:parent.left anchors.leftMargin: 19 anchors.top:parent.top text: section font.pixelSize: 26 color: "#ffffff" font.family: "FZLTHJW--GB1-0" //字體 opacity: 0.9 } } }//sectionHeader is end function calculate_height(count) { console.log("*******count:**********",count) var divisor_count; var remainder_count; var divisor_height; var n divisor_count = Math.floor(count/4); remainder_count = count%4; if(divisor_count === 0) {n =1} else if(divisor_count >= 1) { if(remainder_count === 0) { n = divisor_count; } else { n = divisor_count + 1; } } console.log("*******n:**********",n) divisor_height = 152 + (n -1)*140; console.log("*******divisor_height:**********",divisor_height) return divisor_height; } Component{ id:lisview_gridview Rectangle{ width: ListView.view.width height: calculate_height(fenlei_texts[index%6].length) color: "transparent" border.color: Qt.lighter(color, 1.1) GridView{ id:grid_view property int spacing: 40 model:fenlei_texts[index%6] height:parent.height width:parent.width cellWidth: 300 cellHeight: 140 contentWidth: 0 contentHeight:0 interactive:false delegate: Component{ Rectangle{ id:back color: "#31354d" width: {grid_view.cellWidth - grid_view.spacing} height: {grid_view.cellHeight - grid_view.spacing} visible: grid_text.text === ""?0:1 Text{ id:grid_text anchors.centerIn: parent text:modelData font.pixelSize: 26 color: "#ffffff" font.family: "FZLTHJW--GB1-0" //字體 opacity: 0.9 visible: grid_text.text === ""?0:1 } MouseArea { anchors.fill: parent acceptedButtons: Qt.AllButtons onClicked:{ grid_view.currentIndex = index //實現item切換 console.log("*******grid_currentIndex**********"+index) } onPressed: {back.opacity = 0.3} onReleased: {back.opacity = 1} } } } Component.onCompleted: { grid_view.currentIndex = -1; } } MouseArea { anchors.fill: parent propagateComposedEvents: true onPressed:{ listview.currentIndex = index //實現item切換 grid_view.currentIndex = -1 mouse.accepted = false console.log("*******List_currentIndex**********"+index) } } } } ListView { id:listview x:60 y:152 width: parent.width height: 466 model:phoneModel delegate:lisview_gridview section.property: "manufacture" section.criteria: ViewSection.FullString section.delegate: sectionHeader clip: true } Component.onDestruction: { fenlei_texts.length = 0 } }