iT邦幫忙

2022 iThome 鐵人賽

DAY 27
0
Software Development

[Python QT] 玩玩 Pyside 的各種功能系列 第 27

【Day27】QTreeView 完全新手 - 續續之圖片

  • 分享至 

  • xImage
  •  

今天我們來試試把 Class 的文字用圖片代替

import sys
from PySide6.QtWidgets import *
from PySide6.QtGui import *
from PySide6.QtCore import *

data = {"Saber": {"B":{}, "A":{}, "Q":{}},
        "Archer": {"B": {"EMIYA": {"star": "4"}, "Gilgamesh": {"star": "5"}, "Arjuna": {"star": "5"}, "Kid Gilgamesh": {"star": "3"}}, "A":{}, "Q":{}},
        "Lancer": {"B": {"Karna": {"star": "5"}}, "A": {}, "Q": {"Cu Chulainn": {"star": "3"}}},
        "Rider": {"B": {}, "A": {}, "Q": {"Alexander": {"star": "3"}}},
        "Caster": {"B": {}, "A": {"Zhuge Liang (El-Melloi II)": {"star": "5"}, "Solomon (Grand Caster)": {"star": "5"}},"Q": {}},
        "Assassin": {"B":{}, "A":{}, "Q":{}},
        "Berserker": {"B": {"Cu Chulainn (Alter)": {"star": "5"}}, "A": {}, "Q": {}},
        "Extra" : {"B":{}, "A":{}, "Q":{"Edmond Dantes": {"star": "5"}}}}

class MyWidget(QWidget):
    def __init__(self):
        super().__init__()
        treeV = QTreeView(self)
        treeV.resize(450, 250)
        model = QStandardItemModel(treeV)
        model.setHorizontalHeaderLabels(["Servant", "Star"])
        for key, values in data.items():
            classIcon = QIcon("icon\\"+key+".png")
            itemClass = QStandardItem(classIcon, "")
            for np, sv in values.items():
                itemNP = QStandardItem(np)
                for name, star in sv.items():
                    itemName = QStandardItem(name)
                    itemStar = QStandardItem(star["star"])
                    itemNP.appendRow([itemName, itemStar])
                itemClass.appendRow(itemNP)
            model.appendRow(itemClass)
        treeV.setModel(model)

if __name__ == "__main__":
    app = QApplication([])

    widget = MyWidget()
    widget.resize(500, 300)
    widget.show()

    sys.exit(app.exec())

這邊一樣為了方便, 把圖片名稱跟 data 裡的文字對應上
展示如下
https://ithelp.ithome.com.tw/upload/images/20220929/20151144W29BwgGVTD.png
喔喔喔喔喔喔喔喔喔!!!!!!!!! 可以耶!
雖然圖片有點小, 但是沒關係! 可以塞圖片就代表可以改圖片大小
經過各種嘗試後發現加上 treeV.setIconSize(QSize(80, 50)) 後畫面就可以變成

https://ithelp.ithome.com.tw/upload/images/20220929/201511447b3Kst0IpM.png
喔!!!!!!!!!!!!!!!!!!!!!! 太讚了!

接下來我把之前用過的從者大頭也放上去, QTreeView 還可以直接在標題放圖片, 所以我也直接把星星改成圖片顯示

import sys
from PySide6.QtWidgets import *
from PySide6.QtGui import *
from PySide6.QtCore import *

data = {"Saber": {"Buster":{}, "Arts":{}, "Quick":{}},
        "Archer": {"Buster": {"EMIYA": {"star": "4"}, "Gilgamesh": {"star": "5"}, "Arjuna": {"star": "5"}, "Kid Gilgamesh": {"star": "3"}}, "Arts":{}, "Quick":{}},
        "Lancer": {"Buster": {"Karna": {"star": "5"}}, "Arts": {}, "Quick": {"Cu Chulainn": {"star": "3"}}},
        "Rider": {"Buster": {}, "Arts": {}, "Quick": {"Alexander": {"star": "3"}}},
        "Caster": {"Buster": {}, "Arts": {"Zhuge Liang (El-Melloi II)": {"star": "5"}, "Solomon (Grand Caster)": {"star": "5"}},"Quick": {}},
        "Assassin": {"Buster":{}, "Arts":{}, "Quick":{}},
        "Berserker": {"Buster": {"Cu Chulainn (Alter)": {"star": "5"}}, "Arts": {}, "Quick": {}},
        "Extra" : {"Buster":{}, "Arts":{}, "Quick":{"Edmond Dantes": {"star": "5"}}}}

class MyWidget(QWidget):
    def __init__(self):
        super().__init__()
        treeV = QTreeView(self)
        treeV.resize(450, 250)
        treeV.setIconSize(QSize(80, 30))
        model = QStandardItemModel(treeV)
        model.setHorizontalHeaderItem(0, QStandardItem("Servant"))
        model.setHorizontalHeaderItem(1, QStandardItem(QIcon("icon\star.png"), ""))
        for key, values in data.items():
            itemClass = QStandardItem(QIcon("icon\\"+key+".png"), "")
            for np, sv in values.items():
                itemNP = QStandardItem(QIcon("icon\\"+np+".png"), "")
                for name, star in sv.items():
                    itemName = QStandardItem(QIcon("icon\\"+name+".png"), name)
                    itemStar = QStandardItem(star["star"])
                    itemNP.appendRow([itemName, itemStar])
                itemClass.appendRow(itemNP)
            model.appendRow(itemClass)
        treeV.setModel(model)
        treeV.resize(300, 300)

if __name__ == "__main__":
    app = QApplication([])

    widget = MyWidget()
    widget.adjustSize()
    widget.show()

    sys.exit(app.exec())

目前外觀如下
https://ithelp.ithome.com.tw/upload/images/20220929/201511442jpaUFkQqa.png
感動啊!

不過想起在 QTreeView 中, 每個資料欄位初始是可以讓使用者編輯的, 因此在這裡要把一些編輯關閉
使用 itemClass.setEditable(False) 即可
沒關閉在圖片上雙擊時
https://ithelp.ithome.com.tw/upload/images/20220929/20151144BC8eI41Sbz.png
關閉後雙擊會直接開啟子 item
noEdit

這次想嘗試把星數改成直接用幾顆星星顯示, 異想天開想在 QPixmap 或 QIcon 直接畫多次星星, 找不到方法, 最後只好直接用星星符號代替, 為了文章版面整潔, 在這裡只放 for 迴圈裡的程式碼

for key, values in data.items():
    itemClass = QStandardItem(QIcon("icon\\"+key+".png"), "")
    itemClass.setEditable(False)
    for np, sv in values.items():
        itemNP = QStandardItem(QIcon("icon\\"+np+".png"), "")
        itemNP.setEditable(False)
        for name, star in sv.items():
            itemName = QStandardItem(QIcon("icon\\"+name+".png"), name)
            stars = ""
            for i in range(int(star["star"])):
                stars = stars + "★"
            itemStar = QStandardItem(stars)
            itemNP.appendRow([itemName, itemStar])
        itemClass.appendRow(itemNP)
    model.appendRow(itemClass)
treeV.setModel(model)

展示
https://ithelp.ithome.com.tw/upload/images/20220929/20151144xo3JX0n8h9.png

最後是想放按鈕, 但是還沒找到好法前決定先用 ">>" 代替, 讓 Tree 被點擊到時連接一個函式


上一篇
【Day26】QTreeView 完全新手 - 續
下一篇
【Day28】QTreeView 完全新手 - 續續續之假按鈕
系列文
[Python QT] 玩玩 Pyside 的各種功能31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言