#PYTHON3 #QT #PYSISE2 #TUTORIAL #WIDGET #ITEM
有什麼顯示方式比樹狀、清單、表格更清晰呢?
Python是個非常適合處理文字以及資料的語言,再資料的呈獻方式中最一目了然且簡單的不外乎就是表格、清單以及樹狀圖了。Qt中,我們可以使用ListWidget, TableWidget, TreeWidget來呈現我們的data。
OverView
Item Widget是以Item為主體,每一種Widget都有自己的WidgetItem、以及相同的且類似的函式。
例如:
- QListWidget中的item類型都是QListWidgetItem
- 新增物件則是使用
addItem()
- Item 通常會有data, text, Icon 等屬性
ListWidget
ListWidget可以除了可以條列式的顯示文字以外,也可以在項目中加入圖片,我們也可以對QListWidgetItem做個人化的處理,修改內部參數甚至是StyleSheet來修改外觀。
ListWidgetItem
這邊我們新增一個CreateItem的方法來建立獨立的Item,並設定文字、圖片、對齊等屬性。
from PySide2.QtWidgets import QListWidgetItem, QListView def create_item(self, name, icon, parent): """Create a standard list widget item, for option panel. Args: name: Name of option button icon: Icon name of option button parent: The QListWidget Returns: item: created option button """
item = QListWidgetItem(parent)
item.setText(name)
item.setIcon(QIcon(icon))
item.setStatusTip(name)
item.setTextAlignment(Qt.AlignLeft)
item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
return item
接下來,設定ListWidget本體的屬性並且用List的方式將物件都加入ListWidget中。
# Setup ListWidget
self._list_items.append(self.create_item('Play', './media/play.png'
, self._window.tool_list))
self._list_items.append(self.create_item('Pause','./media/pause.png', self._window.tool_list))
self._list_items.append(self.create_item('Stop', './media/stop.ico'
, self._window.tool_list))
self._window.tool_list.setCurrentRow(0)
self._window.tool_list.setViewMode(QListView.ListMode)
self._window.tool_list.setSpacing(1)
self._window.tool_list.setItemAlignment(QtCore.Qt.AlignCenter)
self._window.tool_list.setEnabled(True)
此外我們也可以用 IconMode的方式來做顯示
self._window.tool_list.setViewMode(QListView.IconMode)
Result
TableWidget
TableWidget非常適合用在顯示表格式的檔案,包括csv, DB, Excel等資料。讓我們用TableWidget來顯示一個類csv的data吧!
Data
我們的data如下:
data_list = list()
data = 'Name Job Level Attack Defense DPS\n' \
'Arey Newbie 5 30 10 0.3\n' \
'Alice Witch 30 150 32 1.0\n' \
'Moly Knight 42 200 70 1.7\n' \
'Cathy Ranger 35 170 41 2.0\n' \
for row in data.split('\n'):
col = row.split(' ')
data_list.append(col)
About Table
表格物件有幾個屬性需要了解,第一個就是表頭,其分為rowHeader以及columnHeader。表個中的每個格子皆為一個QtableWidgetItem,其最主要的屬性就是定位用的row, col還有外觀以及顯示的屬性,包括文字、顏色、圖示等等。
TableWidgetItem
同樣的我們建立一個,Cell的creator
from PySide2.QtWidgets import QTableWidgetItem, QHeaderView def create_cell(self, data: str): """Create data cell on UI.""" cell = QTableWidgetItem(data) cell.setFont(QFont('Free Mono', 11)) cell.setTextAlignment(Qt.AlignVCenter | Qt.AlignHCenter) return cell
TableWidget
接下來設定Table的本體屬性。
有一些比較複雜的設定,像section的縮放模式我使用 QHeaderView.Strech
,另外,也將捲動條給隱藏( horizontalScrollBar().setVisible(False)
)
注意:不要忘記設定
setRowCount
及setColumnCount
不然表格會顯示不出來唷!
table = self._window.data_table table.verticalHeader().setDefaultSectionSize(18) table.verticalHeader().setDefaultAlignment(Qt.AlignCenter) table.verticalHeader().setSectionResizeMode(QHeaderView.Stretch) table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) table.verticalScrollBar().setVisible(False) table.horizontalScrollBar().setVisible(False)header_data = data_list.pop(0) table.setColumnCount(len(header_data)) table.setRowCount(len(data_list))# 設定Header內容 for idx, data in enumerate(header_data): header = self.create_cell(data) table.setHorizontalHeaderItem(idx, header)# 建立Cell 並加入table之中 for row_num, row in enumerate(data_list): for col_num, col_data in enumerate(row): item = self.create_cell(col_data) item.setToolTip('row{},Col{}'.format(row_num, col_num)) table.setItem(row_num, col_num, item)
Result
TreeWidget
TreeWidget可以說是list與table的結合與延伸,除了有Header欄位,同時也是條列式的顯示。而最核心的當然就是多層次的顯示及縮小展開功能。
Root & Child
TreeWidget的分支有分為root以及child兩個階層,而child底下還可以有child,但root只會再最上層並且宣告時要指定parent的TreeWidget為何。
from PySide2.QtGui import QFont, QColor from PySide2.QtWidgets import QTreeWidgetItemdef create_root(self, parent, name, value): """Create root item of the tree""" root = QTreeWidgetItem(parent) root.setText(0, name) root.setText(1, value) root.setTextColor(0, QColor('#ffffff')) root.setTextColor(1, QColor('#ffffff')) root.setBackgroundColor(0, QColor('#0066cc')) root.setBackgroundColor(1, QColor('#0066cc')) return root def create_child(self, name, value): """Create child item of the tree""" root = QTreeWidgetItem() root.setText(0, name) root.setText(1, value) root.setTextColor(0, QColor('#0066cc')) root.setTextColor(1, QColor('#0066cc')) root.setBackgroundColor(0, QColor('#ccffff')) root.setBackgroundColor(1, QColor('#ccffff')) return root
TreeWidget
TreeWidget也有header可以設定,其可以是QLabel也可以是QTreeWidgetItem的類別。
- 這邊我們利用文章最上面的勇者資料來當作我們的素材
# Setup TreeWidget
tree = self._window.hero_tree
tree.setIndentation(5)
tree.setColumnCount(2)
tree.setFont(QFont('Free Mono', 11))
header = QTreeWidgetItem(['Name', 'Value'])
tree.setHeaderItem(header)
for hero in data_list:
hero_root = self.create_root(tree, header_data[0], hero[0])
for idx in range(1, len(hero)):
hero_attr = self.create_child(header_data[idx], hero[idx])
hero_root.addChild(hero_attr)
Result
Source Code
完整代碼請看 : Item Widget
結論
ItemWidget對於資料顯示非常實用,同時還有其他互動式介面會用到的設計方法,這部份我們後面的教學會提到唷,請大家期待一下吧!另外,肯定友人提到非常類似的Model模式的viewWidget物件,主要以顯示為主,優點在於可以導入model的物件,例如:用QDirFileSystemModel來製作file browser等等。