前言
在开发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_()
不要因为事与愿违而感到惊讶,
因为这个宇宙比你大的多。
——阿兰·德波顿
评论
859790 973286How is the new year going? I hope to read far more fascinating posts like last year 864475
624351 888196I was reading via some of your content material on this internet site and I believe this site is really instructive! Maintain putting up. 386635
668041 138529Appreciate it for helping out, superb info. 4736
485542 498932Yay google is my king assisted me to discover this outstanding internet site! . 644319
915844 282413Excellent post even so , I was wanting to know if you could write a litte far more on this subject? Id be very thankful in the event you could elaborate just a little bit further. Bless you! 172407
810742 134203Perfectly indited content , thanks for selective information . 998989