前言
在开发Qt界面时,经常会用到一些嵌套式控件,例如列表控件QlistWidget、树形控件QTreeWidget、表格控件QTableWidget。
同时Qt中也有QListView、QTreeView、QtableView,区别是前者是Item-Based,使用起来更简单,后者是Model-Based,功能更强大。
因此接下来用几篇文章就整理一下常用的这三种控件的使用方法,今天先来说一下QListWidget和QListView。
QListWidget的使用
在使用QListWidget时,经常会和复选框QCheckBox嵌套使用,例如下面的例子。
这个简单的例子有基本的增删查功能,并且有复选框和图标,能够对单击和双击事件进行响应,代码如下:
from Qt import QtCore, QtWidgets, QtGui from Qt.QtCompat import load_ui, QFileDialog class testPanel(QtWidgets.QWidget): def __init__(self): super(testPanel, self).__init__() DIR, file_name = os.path.split(os.path.abspath(__file__)) load_ui(os.path.join(DIR, "ListWidget.ui"), self) self.listWidget.setIconSize(QtCore.QSize(15,10)) self.bindEvent() def bindEvent(self): self.pushButton.clicked.connect(self.add) self.pushButton_2.clicked.connect(self.remove) self.pushButton_3.clicked.connect(self.all) self.pushButton_4.clicked.connect(self.clear) self.listWidget.itemDoubleClicked.connect(self.dbclick) # add Item def add(self): text = self.lineEdit.text().strip() if text: item = QtWidgets.QListWidgetItem(text) icon = QtGui.QIcon("D:/img538.jpg") item.setIcon(icon) item.setCheckState(QtCore.Qt.Checked) self.listWidget.addItem(item) # remove Item def remove(self): selectedRow = self.listWidget.currentRow() if selectedRow != -1: self.listWidget.takeItem(selectedRow) # select all Items def all(self): for i in range(self.listWidget.count()): item = self.listWidget.item(i) item.setCheckState(QtCore.Qt.Checked) # unselect all Items def clear(self): for i in range(self.listWidget.count()): item = self.listWidget.item(i) item.setCheckState(QtCore.Qt.Unchecked) # get all selected Items def get_data(self): allData = [] for i in range(self.listWidget.count()): item = self.listWidget.item(i) if item.checkState(): allData.append(item.text()) return allData # Item DoubleClicked def dbclick(self): self.label.setText("ListWidgetItem been dbClicked!") app = QtWidgets.QApplication(sys.argv) mt = testPanel() mt.show() app.exec_()
常用的样式如下:
QListWidget { background: #222222; } QListWidget::item { background: #bbbbbb; } QListWidget::item:hover { background: #ffffff; } QListWidget::item:selected { background: #cccccc; } 复选框样式 QListWidget::indicator::checked{ image: url(D:/ico/selected.png); }
上面的案例里面的子项比较简单,只有复选框、图标、文字,是通过item方式来添加子项的,而如果子项比较复杂,例如歌曲列表,每项都有独立的歌名、作者、专辑、图片、按钮、进度条等等,这种时候可以使用itemWidget方式添加Widget子项。
例如下面的例子。
如上图,每一行都是一个小的Widget,实现也很简单,代码如下:
import os from Qt import QtCore, QtWidgets, QtGui from Qt.QtCompat import load_ui, QFileDialog # 行控件 class songItem(QtWidgets.QWidget): def __init__(self,count,name,artist,CD,time): super(songItem, self).__init__() DIR, file_name = os.path.split(os.path.abspath(__file__)) load_ui(os.path.join(DIR, "song.ui"), self) self.count = count self.name = name self.artist = artist self.CD = CD self.time = time self.initUI() self.initData() def initUI(self): favIcon = QtGui.QIcon("fav.png") self.pushButton_Fav.setIcon(favIcon) downIcon = QtGui.QIcon("down.png") self.pushButton_Down.setIcon(downIcon) qss = """QPushButton{ background:transparent; border:none; } """ self.pushButton_Fav.setStyleSheet(qss) self.pushButton_Down.setStyleSheet(qss) def initData(self): self.label_Num.setText(str(self.count)) self.label_Name.setText(self.name) self.label_Artist.setText(self.artist) self.label_CD.setText(self.CD) self.label_Time.setText(self.time) # 主体窗口 class testPanel(QtWidgets.QWidget): def __init__(self): super(testPanel, self).__init__() DIR, file_name = os.path.split(os.path.abspath(__file__)) load_ui(os.path.join(DIR, "ListWidget.ui"), self) self.initui() self.datas = [["いかないで","鹿乃","two","03:02"],["フラレガイガール","さユり","フラレガイガール","06:07"],["ワタシノテンシ","雨宫天","好きすぎてやばい","04:22"]] self.bindEvent() self.add() def initui(self): qss = """ QListWidget { outline: 0px; } QListWidget::item { height:40px; padding: 0px; } """ self.listWidget.setStyleSheet(qss) def bindEvent(self): self.pushButton.clicked.connect(self.add) self.pushButton_2.clicked.connect(self.remove) # self.pushButton_3.clicked.connect(self.all) # self.pushButton_4.clicked.connect(self.clear) self.listWidget.itemClicked.connect(self.click) self.listWidget.itemDoubleClicked.connect(self.dbclick) def add(self): for i in range(len(self.datas)): itemWidget = songItem(i+1,self.datas[i][0],self.datas[i][1],self.datas[i][2],self.datas[i][3]) item = QtWidgets.QListWidgetItem() self.listWidget.addItem(item) self.listWidget.setItemWidget(item, itemWidget) self.listWidget.addItem(item) def remove(self): selectedItems = self.listWidget.selectedItems() if selectedItems: self.listWidget.takeItem(self.listWidget.row(selectedItems[0])) def get_data(self): allData = [] for i in range(self.listWidget.count()): item = self.listWidget.itemWidget(self.listWidget.item(i)) allData.append(item.label_Name.text()) return allData def click(self): selectedItems = self.listWidget.selectedItems() if selectedItems: item = self.listWidget.itemWidget(selectedItems[0]) self.label.setText(item.label_Name.text() + " been Clicked!") def dbclick(self): selectedItems = self.listWidget.selectedItems() if selectedItems: item = self.listWidget.itemWidget(selectedItems[0]) self.label.setText(item.label_Name.text() + " been DoubleClicked!") app = QtWidgets.QApplication(sys.argv) mt = testPanel() mt.show() app.exec_()
QListView的使用
相比于QListWidget,QListView是使用Model/View结构来管理数据与视图的关系, model负责数据的存取。
QT提供了一些现成的models用于处理数据项:
- QStringListModel 用于存储简单的QString列表。
- QStandardItemModel 管理复杂的树型结构数据项,每项都可以包含任意数据。
- QDirModel 提供本地文件系统中的文件与目录信息。
- QSqlQueryModel, QSqlTableModel,QSqlRelationTableModel用来访问数据库。
这里先以QStringListModel为例,看下面的例子。
这个简单的例子有基本的增删改查功能,也能正常触发单击、双击事件,代码如下:
import os from Qt import QtCore, QtWidgets, QtGui from Qt.QtCompat import load_ui, QFileDialog class testPanel(QtWidgets.QWidget): def __init__(self): super(testPanel, self).__init__() DIR, file_name = os.path.split(os.path.abspath(__file__)) load_ui(os.path.join(DIR, "ListView.ui"), self) self.qList = ["Item1", "Item2", "Item3", "Item4"] self.bindEvent() self.initData() def bindEvent(self): self.pushButton.clicked.connect(self.add) self.pushButton_2.clicked.connect(self.remove) self.listView.clicked.connect(self.click) self.listView.doubleClicked.connect(self.dbclick) def initData(self): self.model = QtCore.QStringListModel() self.model.setStringList(self.qList) self.listView.setModel(self.model) def add(self): text = self.lineEdit.text().strip() if text: row = self.model.rowCount() self.model.insertRow(row) self.model.setData(self.model.index(row), text) def remove(self): selectedIndex = self.listView.currentIndex() if selectedIndex: self.model.removeRow(selectedIndex.row()) def get_data(self): return self.model.stringList() def click(self, qModelIndex): self.label.setText(self.model.stringList()[qModelIndex.row()] + " been Clicked!") def dbclick(self,qModelIndex): self.label.setText(self.model.stringList()[qModelIndex.row()] + " been DoubleClicked!") app = QtWidgets.QApplication(sys.argv) mt = testPanel() mt.show() app.exec_()
常用的样式与QListWidget相同,如下:
QListView { background: red; } QListView::item { height: 30px; background: blue; } QListView::item:selected { border:2px solid #6a6ea9; } QListView::item::hover { background:qlineargradient(x1:0, y1:0,x2:1,y2:0, stop:0 #000000, stop:1 #ffffff); } QListView::indicator::checked{ image: url(D:/img538.jpg); }
接下来是比较常用的QStandardItemModel,案例如下:
与QListWidget的第一个案例几乎没有区别,只是多了双击可以编辑的功能,代码如下:
import os from Qt import QtCore, QtWidgets, QtGui from Qt.QtCompat import load_ui, QFileDialog class testPanel(QtWidgets.QWidget): def __init__(self): super(testPanel, self).__init__() DIR, file_name = os.path.split(os.path.abspath(__file__)) load_ui(os.path.join(DIR, "ListView.ui"), self) self.bindEvent() self.initData() def bindEvent(self): self.pushButton.clicked.connect(self.add) self.pushButton_2.clicked.connect(self.remove) self.pushButton_3.clicked.connect(self.all) self.pushButton_4.clicked.connect(self.clear) self.listView.clicked.connect(self.click) self.listView.doubleClicked.connect(self.dbclick) def initData(self): self.model = QtGui.QStandardItemModel() self.listView.setModel(self.model) def add(self): text = self.lineEdit.text().strip() if text: item = QtGui.QStandardItem(text) item.setCheckable(True) item.setCheckState(QtCore.Qt.Checked) item.setData(QtGui.QIcon("D:/img538.jpg"), QtCore.Qt.DecorationRole) self.model.appendRow(item) def remove(self): selectedIndex = self.listView.currentIndex() if selectedIndex: self.model.removeRow(selectedIndex.row()) def all(self): i = 0 while self.model.item(i): item = self.model.item(i) if not item.checkState(): item.setCheckState(QtCore.Qt.Checked) i += 1 def clear(self): i = 0 while self.model.item(i): item = self.model.item(i) if item.checkState(): item.setCheckState(QtCore.Qt.Unchecked) i += 1 def get_data(self): choices = [] i = 0 while self.model.item(i): if self.model.item(i).checkState(): choices.append(self.model.item(i).text()) i += 1 return choices def click(self, qModelIndex): print(qModelIndex.row()) self.label.setText(self.model.item(qModelIndex.row()).text() + " been Clicked!") def dbclick(self,qModelIndex): self.label.setText(self.model.item(qModelIndex.row()).text() + " been DoubleClicked!") app = QtWidgets.QApplication(sys.argv) mt = testPanel() mt.show() app.exec_()
不要因为事与愿违而感到惊讶,
因为这个宇宙比你大的多。
——阿兰·德波顿
评论
825418 630011Fantastic web site, determined several something totally new! Subscribed RSS for later, aspire to see far more updates exactly like it. 112706