QListWidget 列表選擇框
QListWidget 是 PyQt6 裡的列表選擇框元件,這篇教學會介紹如何在 PyQt6 視窗裡加入 QListWidget 列表選擇框,並簡單介紹與 QListView 的差異,並實作修改樣式以及點擊選項等基本應用。
快速導覽:
因為 Google Colab 不支援 PyQt6,所以請使用本機環境 ( 參考:使用 Python 虛擬環境 ) 或使用 Anaconda Jupyter 進行實作 ( 參考:使用 Anaconda )。
QListWidget 和 QListView 的差異
QListWidget 是一個更新且更高級的元件,能夠更為方便地進行開發,例如 QListWidget 具有 QStantandardItemModel 無法訪問的類型,也能更輕鬆的透過 QListWidgetItem 處理數據,然而如果使用 QListView,許多方法必須要額外定義,屬於比較舊的使用方式。
下方列出兩個方法所建立簡單列表選單的程式碼,可以看出使用 QListWidget 的程式碼更容易閱讀理解:
from PyQt6 import QtWidgets, QtCore
import sys
app = QtWidgets.QApplication(sys.argv)
Form = QtWidgets.QWidget()
Form.setWindowTitle('oxxo.studio')
Form.resize(300, 200)
# 使用 QListView
listview = QtWidgets.QListView(Form)
listview.setGeometry(10,10,120,100)
model = QtCore.QStringListModel()
model.setStringList(['A','B','C','D']) # 使用 QtCore.QStringListModel() 建立選單
listview.setModel(model)
# 使用 QListWidget
listwidget = QtWidgets.QListWidget(Form)
listwidget.setGeometry(140,10,120,100)
listwidget.addItems(['A','B','C','D']) # 使用 addItems 建立選單
Form.show()
sys.exit(app.exec())
加入 QListWidget 列表選擇框
建立 PyQt6 視窗物件後,透過 QtWidgets.QListWidget(widget)
方法,就能在指定的元件中建立列表選擇框,接著使用 addItems()
方法加入列表項目,下方的程式碼執行後,會在視窗裡加入一個有四個項目的列表選擇框。
from PyQt6 import QtWidgets
import sys
app = QtWidgets.QApplication(sys.argv)
Form = QtWidgets.QWidget()
Form.setWindowTitle('oxxo.studio')
Form.resize(300, 200)
listwidget = QtWidgets.QListWidget(Form) # 建立列表選擇框元件
listwidget.addItems(['A','B','C','D']) # 建立選單
listwidget.setGeometry(10,10,120,100) # 設定位置
Form.show()
sys.exit(app.exec())
class 寫法:
from PyQt6 import QtWidgets
import sys
class MyWidget(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('oxxo.studio')
self.resize(300, 200)
self.ui()
def ui(self):
self.listwidget = QtWidgets.QListWidget(self) # 建立列表選擇框元件
self.listwidget.addItems(['A','B','C','D']) # 建立選單
self.listwidget.setGeometry(10,10,120,100) # 設定位置
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
Form = MyWidget()
Form.show()
sys.exit(app.exec())
QListWidget 刪除選項
使用使用 takeItem(index)
取得指定的項目,index 表示該項目的索引值,第一個項目為 0,取得項目後,就能透過 removeItemWidge(item)
方法移除該項目,下方的程式碼執行後,會將項目裡的 B 移除。
from PyQt6 import QtWidgets
import sys
app = QtWidgets.QApplication(sys.argv)
Form = QtWidgets.QWidget()
Form.setWindowTitle('oxxo.studio')
Form.resize(300, 200)
listwidget = QtWidgets.QListWidget(Form)
listwidget.addItems(['A','B','C','D'])
listwidget.setGeometry(10,10,120,100)
item = listwidget.takeItem(1) # 取得第二個項目,也就是 B
listwidget.removeItemWidget(item) # 移除第二個項目
Form.show()
sys.exit(app.exec())
class 寫法:
from PyQt6 import QtWidgets
import sys
class MyWidget(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('oxxo.studio')
self.resize(300, 200)
self.ui()
def ui(self):
self.listwidget = QtWidgets.QListWidget(self)
self.listwidget.addItems(['A','B','C','D'])
self.listwidget.setGeometry(10,10,120,100)
item = self.listwidget.takeItem(1) # 取得第二個項目,也就是 B
self.listwidget.removeItemWidget(item) # 移除第二個項目
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
Form = MyWidget()
Form.show()
sys.exit(app.exec())
QListWidget 添加選項
有兩種方法可以「添加列表項目」,第一種方法使用 addItem(item)
方法將項目加在列表最後方,第二種方法使用 insertItem(index, item)
將項目加入指定的位置,兩種方法除了可以單純加入「文字」項目,也可以使用函式的方法,加入帶有 icon 圖示的項目。
下面的程式碼執行後,會先使用第一種方法,在最後方添加一個內容為 X 的項目,並搭配函式在最後加入一個帶有 icon 圖片的選項,接著會使用第二種方法,將內容為 Y 的項目添加在第一個項目,然後再搭配函式在第一個項目加入帶有 icon 圖片的選項。
from PyQt6 import QtWidgets, QtGui
import sys
app = QtWidgets.QApplication(sys.argv)
Form = QtWidgets.QWidget()
Form.setWindowTitle('oxxo.studio')
Form.resize(300, 200)
def create_item(text, img):
item = QtWidgets.QListWidgetItem() # 建立清單項目
item.setText(text) # 項目文字
item.setIcon(QtGui.QIcon(img)) # 項目圖片
return item # 返回清單項目
listwidget = QtWidgets.QListWidget(Form)
listwidget.addItems(['A','B','C','D'])
listwidget.setGeometry(10,10,120,120)
listwidget.addItem('X') # 添加純文字項目
listwidget.addItem(create_item('', 'icon.png')) # 添加使用函式創造的選項
listwidget.insertItem(0, 'Y') # 添加純文字項目
listwidget.insertItem(0, create_item('', 'mona.jpg')) # 添加使用函式創造的選項
Form.show()
sys.exit(app.exec())
class 寫法:
from PyQt6 import QtWidgets, QtGui
import sys
class MyWidget(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('oxxo.studio')
self.resize(300, 200)
self.ui()
def ui(self):
self.listwidget = QtWidgets.QListWidget(self)
self.listwidget.addItems(['A','B','C','D'])
self.listwidget.setGeometry(10,10,120,120)
self.listwidget.addItem('X') # 添加純文字項目
self.listwidget.addItem(self.create_item('', 'icon.png')) # 添加使用函式創造的選項
self.listwidget.insertItem(0, 'Y') # 添加純文字項目
self.listwidget.insertItem(0, self.create_item('', 'mona.jpg')) # 添加使用函式創造的選項
def create_item(self, text, img):
item = QtWidgets.QListWidgetItem() # 建立清單項目
item.setText(text) # 項目文字
item.setIcon(QtGui.QIcon(img)) # 項目圖片
return item # 返回清單項目
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
Form = MyWidget()
Form.show()
sys.exit(app.exec())
QListWidget 修改選項
如果要修改項目內容,可以先透過 item(index)
方法可以取得該項目,接著就能使用 setText()
方法修改文字,使用 setIcon()
方法設定圖示。
from PyQt6 import QtWidgets, QtGui
import sys
app = QtWidgets.QApplication(sys.argv)
Form = QtWidgets.QWidget()
Form.setWindowTitle('oxxo.studio')
Form.resize(300, 200)
listwidget = QtWidgets.QListWidget(Form)
listwidget.addItems(['A','B','C','D'])
listwidget.setGeometry(10,10,120,100)
item = listwidget.item(1) # 取得第二個項目 ( 第一個為 0 )
item.setText('ok') # 設定文字為 ok
item.setIcon(QtGui.QIcon('icon.png')) # 設定 icon
Form.show()
sys.exit(app.exec())
class 寫法:
from PyQt6 import QtWidgets, QtGui
import sys
class MyWidget(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('oxxo.studio')
self.resize(300, 200)
self.ui()
def ui(self):
self.listwidget = QtWidgets.QListWidget(self)
self.listwidget.addItems(['A','B','C','D'])
self.listwidget.setGeometry(10,10,120,100)
item = self.listwidget.item(1) # 取得第二個項目 ( 第一個為 0 )
item.setText('ok') # 設定文字為 ok
item.setIcon(QtGui.QIcon('icon.png')) # 設定 icon
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
Form = MyWidget()
Form.show()
sys.exit(app.exec())
QListWidget 樣式設定
透過 setStyleSheet()
,可以使用類似網頁的 CSS 語法設定 QPushButton 樣式,搭配 setFlow()
方法,也可以設定列表為水平顯示或垂直顯示 ( QtWidgets.QListView.Flow.LeftToRight
為 PyQt6 的用法 ),下方的程式碼執行後,會將原本垂直顯示列表換成水平顯示,並在選擇項目時,將項目變成黑底紅字。
from PyQt6 import QtWidgets, QtGui
import sys
app = QtWidgets.QApplication(sys.argv)
Form = QtWidgets.QWidget()
Form.setWindowTitle('oxxo.studio')
Form.resize(300, 200)
def show():
print(listwidget.currentItem().text(), listwidget.currentIndex().row())
def create_item(text):
item = QtWidgets.QListWidgetItem(listwidget)
item.setText(text)
item.setIcon(QtGui.QIcon('icon.png'))
return item
listwidget = QtWidgets.QListWidget(Form)
listwidget.addItems(['A','B','C','D'])
listwidget.setGeometry(10,10,200,50)
listwidget.addItem(create_item(''))
listwidget.setFlow(QtWidgets.QListView.Flow.LeftToRight) # 改成水平顯示
listwidget.setStyleSheet('''
QListWidget{
color:#00f;
}
QListWidget::item{
width:30px;
}
QListWidget::item:selected{
color:#f00;
background:#000;
}
''')
Form.show()
sys.exit(app.exec())
class 寫法:
from PyQt6 import QtWidgets, QtGui
import sys
class MyWidget(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('oxxo.studio')
self.resize(300, 200)
self.ui()
def ui(self):
self.listwidget = QtWidgets.QListWidget(self)
self.listwidget.addItems(['A','B','C','D'])
self.listwidget.setGeometry(10,10,200,50)
self.listwidget.addItem(self.create_item(''))
self.listwidget.setFlow(QtWidgets.QListView.Flow.LeftToRight) # 改成水平顯示
self.listwidget.setStyleSheet('''
QListWidget{
color:#00f;
}
QListWidget::item{
width:30px;
}
QListWidget::item:selected{
color:#f00;
background:#000;
}
''')
def create_item(self, text):
item = QtWidgets.QListWidgetItem(self.listwidget)
item.setText(text)
item.setIcon(QtGui.QIcon('icon.png'))
return item
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
Form = MyWidget()
Form.show()
sys.exit(app.exec())
QListWidget 常用方法
下方列出 QListWidget 的常用方法:
方法 | 參數 | 說明 |
---|---|---|
item() | index | 取得指定的項目。 |
addItem() | str | 增加單一個項目。 |
addItems() | list | 以串列方式增加多個項目。 |
takeItem() | index | 取得並移除指定項目 |
removeItemWidget() | item | 移除指定項目。 |
clear() | 清空所有項目。 | |
setFlow() | type | 設定排列方式,預設 QtWidgets.QListView.Flow.TopToBottom 從上而下,QtWidgets.QListView.Flow.LeftToRight 從左到右 ( 和 PyQt5 不同 )。 |
setDisabled() | bool | 設定是否禁用,預設 False。 |
clicked.connect() | fn | 點擊項目時時要執行的函式。 |
text() | 取得輸入框內容。 | |
currentItem().text() | 點擊項目的文字。 | |
currentIndex().row() | 點擊項目的列數 ( 垂直 )。 | |
currentIndex().column() | 點擊項目的欄數 ( 水平 )。 |
下方列出 QListWidget 裡 item 的常用方法:
方法 | 參數 | 說明 |
---|---|---|
setText() | str | 設定項目的文字內容。 |
setIcon() | QtGui.QIcon(path) | 設定項目的圖片。 |
setSelected() | bool | 設定是否選取,預設 False。 |
text() | 項目的文字內容。 |
顯示 QListWidget 選擇項目
運用 clicked.connect(fn)
方法,就能在點擊項目時,執行特定的函式,下方的程式碼執行後,會透過 QLabel 顯示點擊的項目內容。
from PyQt6 import QtWidgets, QtCore, QtGui
import sys
app = QtWidgets.QApplication(sys.argv)
Form = QtWidgets.QWidget()
Form.setWindowTitle('oxxo.studio')
Form.resize(300, 200)
label = QtWidgets.QLabel(Form)
label.setGeometry(10,10,120,30)
def show():
text = listwidget.currentItem().text() # 取得項目文字
num = listwidget.currentIndex().row() # 取得項目編號
label.setText(f'{num}:{text}') # 顯示文字
listwidget = QtWidgets.QListWidget(Form)
listwidget.addItems(['A','B','C','D'])
listwidget.setGeometry(10,50,120,50)
listwidget.setFlow(QtWidgets.QListView.Flow.LeftToRight)
listwidget.setStyleSheet('''
QListWidget::item{
font-size:20px;
}
QListWidget::item:selected{
color:#f00;
background:#000;
}
''')
listwidget.clicked.connect(show) # 點擊項目時執行函式
Form.show()
sys.exit(app.exec())
class 寫法 ( 注意不能使用 show 作為方法名稱,會覆寫基底的 show 方法造成無法顯示 ):
from PyQt6 import QtWidgets, QtGui
import sys
class MyWidget(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('oxxo.studio')
self.resize(300, 200)
self.ui()
def ui(self):
self.label = QtWidgets.QLabel(self)
self.label.setGeometry(10,10,120,30)
self.listwidget = QtWidgets.QListWidget(self)
self.listwidget.addItems(['A','B','C','D'])
self.listwidget.setGeometry(10,50,120,50)
self.listwidget.setFlow(QtWidgets.QListView.Flow.LeftToRight)
self.listwidget.setStyleSheet('''
QListWidget::item{
font-size:20px;
}
QListWidget::item:selected{
color:#f00;
background:#000;
}
''')
self.listwidget.clicked.connect(self.showText) # 點擊項目時執行函式
def showText(self):
text = self.listwidget.currentItem().text() # 取得項目文字
num = self.listwidget.currentIndex().row() # 取得項目編號
self.label.setText(f'{num}:{text}') # 顯示文字
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
Form = MyWidget()
Form.show()
sys.exit(app.exec())
意見回饋
如果有任何建議或問題,可傳送「意見表單」給我,謝謝~