列表控件可以让我们以列表形式呈现内容,使界面更加有序美观。QListWidget列表控件应当与QListWidgetItem一起使用,后者作为项被添加入列表控件中,也就是说列表控件中的每一项都是一个QListWidgetItem。这也是为什么我们说QListWidget是一个基于项(Item-based)的控件了。
笔者曾经做了一个可以方便生成报价表的桌面小程序,截图如下:
程序中就用到了QListWidget,当选择一种产品系列后,左边的列表空间就会显示该系列的所有内容,然后双击其中的某项就可以在右边的列表控件中显示所双击的项:
我们就通过实现这个简单的功能来学习下QListWidget。
import sysfrom PyQt5.QtGui import QPixmapfrom PyQt5.QtWidgets import QApplication, QWidget, QLabel, QListWidget, QListWidgetItem, QHBoxLayoutclass Demo(QWidget): def __init__(self): super(Demo, self).__init__() self.pic_label = QLabel(self) # 1 self.pic_label.setPixmap(QPixmap('arrow.png')) self.listwidget_1 = QListWidget(self) # 2 self.listwidget_2 = QListWidget(self) self.listwidget_1.doubleClicked.connect(lambda: self.change_func(self.listwidget_1)) self.listwidget_2.doubleClicked.connect(lambda: self.change_func(self.listwidget_2)) for i in range(6): # 3 text = 'Item {}'.format(i) self.item = QListWidgetItem(text) self.listwidget_1.addItem(self.item) self.item_6 = QListWidgetItem('Item 6', self.listwidget_1) # 4 self.listwidget_1.addItem('Item 7') # 5 str_list = ['Item 9', 'Item 10'] self.listwidget_1.addItems(str_list) self.item_8 = QListWidgetItem('Item 8') # 6 self.listwidget_1.insertItem(8, self.item_8) # self.listwidget_1.insertItem(8, 'Item 8') self.h_layout = QHBoxLayout() self.h_layout.addWidget(self.listwidget_1) self.h_layout.addWidget(self.pic_label) self.h_layout.addWidget(self.listwidget_2) self.setLayout(self.h_layout) def change_func(self, listwidget): # 7 if listwidget == self.listwidget_1: item = QListWidgetItem(self.listwidget_1.currentItem()) self.listwidget_2.addItem(item) print(self.listwidget_2.count()) else: self.listwidget_2.takeItem(self.listwidget_2.currentRow()) print(self.listwidget_2.count())if __name__ == '__main__': app = QApplication(sys.argv) demo = Demo() demo.show() sys.exit(app.exec_())
1. pic_label用于显示图片;
2. 实例化两个QListWidget,listwidget_1放在左边用于显示可选的内容,listwidget_2放在右边用于显示被双击的项。然后将这两个QListWidget控件的doubleClicked信号和自定义的槽函数连接起来,每当双击QListWidget中的某项时,就会触发该槽函数。
3. 循环创建六个QListWidgetItem,并通过调用addItem(QListWidgetItem)将其添加到listwidget_1中;
4. 当然也可以通过实例化时直接指定父类的方式进行添加;
5. 也可以不用QListWidgetItem,直接调用addItem(str)方法来添加一项内容。也可以使用addItem(Iterable)来添加一组项内容(不过若要让项呈现更多功能的话,还是应该选择QListWidgetItem);
6. 通过insertItem(row, QListWidgetItem)方法可以在指定行中加入一项内容;
7. 接下来我们讲一下槽函数:
def change_func(self, listwidget): if listwidget == self.listwidget_1: item = QListWidgetItem(self.listwidget_1.currentItem()) self.listwidget_2.addItem(item) print(self.listwidget_2.count()) else: self.listwidget_2.takeItem(self.listwidget_2.currentRow()) print(self.listwidget_2.count())
在槽函数中,我们判断信号是哪一个QListWidget发出的,如果是listwidget_1的话,我们先通过currentItem()获取到当前被双击的项,之后实例化为QListWidgetItem,再通过addItem(QListWidgetItem)方法加入listwidget_2中,count()方法用于获取项数量,这里我们打印出listwidget_2中一共有多少项内容。若信号是listwidget_2发出的话,则将当前被双击项的行数传给takeItem(int)方法来进行删除,然后也打印下项数量。
bug report:currentItem()的返回值是QListWidgetItem,照理来说应该是可以直接被添加的,也就是说下方这种写法应该也是可以的,但是却没有用:
self.listwidget_2.addItem(self.listwidget_1.currentItem())
图片下载地址:
arrow.png: https://www.easyicon.net/download/png/3980/64/
运行截图如下,双击左边的某项,会发现右边的列表控件会显示出来:
双击右边的某项将其删除: