PyQt入门(8)-常用控件(下)

目录

1、QListWidget

2、QTreeWidget 

3、QTableWidget


1、QListWidget

QListWidget是一个QListView的便捷类,提供一个列表视图,大数据量的情况下QListView确实更加灵活,效率更高。但是在少量数据的时候,因为易用性,QListWidget也是一个不错的选择。

QListWidget的每个数据项都是一个QListWidgetItem。

更多用法见:QListWidget详细说明

下面是一个QListWidget的简单用法:

self.list_widget = QListWidget()
self.list_widget.addItem("数据1")
self.list_widget.addItem("数据2")
self.list_widget.addItem("数据3")
self.list_widget.addItem("数据4")
self.main_layout.addWidget(self.list_widget)

再结合前面的知识实现一个简易的目录浏览器:

import os

from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QLineEdit, QPushButton,  \
    QListWidgetItem, QListWidget, QHBoxLayout


class ButtonWindow(QWidget):

    def __init__(self):
        super().__init__()
        self.setWindowTitle('测试button')
        self.resize(400, 300)

        self.layout_main = QVBoxLayout()

        self.layout_header = QHBoxLayout()
        self.le_folder_addr = QLineEdit()
        self.btn_view = QPushButton("浏览")
        # 信号与槽
        self.btn_view.clicked.connect(self.view_folder)
        self.layout_header.addWidget(self.le_folder_addr, stretch=1)
        self.layout_header.addWidget(self.btn_view)
        self.layout_main.addLayout(self.layout_header)

        self.list_widget = QListWidget()
        self.layout_main.addWidget(self.list_widget)

        self.setLayout(self.layout_main)

    def view_folder(self):
        for entry in os.scandir(self.le_folder_addr.text()):
            if entry.is_dir():
                self.list_widget.addItem(QListWidgetItem(QIcon('icons/folder.png'), entry.name))
            else:
                self.list_widget.addItem(QListWidgetItem(QIcon('icons/file.png'), entry.name))

 

2、QTreeWidget 

QTreeWidget是QTreeView的便捷类,提供一个树形视图。QTreeWidget的每个结点都是一个QTreeWidgetItem。直接挂靠在QTreeWidget下的结点是top结点,top结点没有父结点,其他结点在代码上和QTreeWidget已经没有关系了,只需要指定父结点即可,我们可以从QTreeWidgetItem详细说明里面看到QTreeWidgetItem的构造函数大多要指定一个parent。

QTreeWidget使用addTopLevelItem()来添加top结点。

QTreeWidget有columns的概念,我们可以用windows文件夹的详细信息浏览方式为例来理解:

QTreeWidget在第一列展示树形视图,我们可以添加2、3、4 ... 列来展示结点的更多属性。

QTreeWidget还可以设置header信息,更多用法参见:QTreeWidget详细说明

还是上面的简易文件夹浏览器,我们希望能够进一步浏览子目录,并且要体现层级关系,可以用QTreeWidget来改写上面的代码:

class ButtonWindow(QWidget):

    def __init__(self):
        super().__init__()
        self.setWindowTitle('测试button')
        self.resize(400, 300)

        self.layout_main = QVBoxLayout()

        self.layout_header = QHBoxLayout()
        self.le_folder_addr = QLineEdit()
        self.btn_view = QPushButton("浏览")
        self.btn_view.clicked.connect(self.view_folder)
        self.layout_header.addWidget(self.le_folder_addr, stretch=1)
        self.layout_header.addWidget(self.btn_view)
        self.layout_main.addLayout(self.layout_header)

        # 改用QTreeWidget来展示,树形才能展示目录的层级关系
        self.tree_widget = QTreeWidget()
        # 设置标题为 名称
        self.tree_widget.setHeaderLabel("名称")

        self.layout_main.addWidget(self.tree_widget)

        self.setLayout(self.layout_main)

    def view_folder(self):
        for entry in os.scandir(self.le_folder_addr.text()):
            if entry.is_dir():
                temp = QTreeWidgetItem([entry.name])
                temp.setIcon(0, QIcon('icons/folder.png'))
                # 添加top结点
                self.tree_widget.addTopLevelItem(temp)
                # 子目录下的结点以此top结点为root形成一颗结点树
                self.digui_view(os.path.join(self.le_folder_addr.text(), entry.name), temp)
            else:
                temp = QTreeWidgetItem([entry.name])
                temp.setIcon(0, QIcon('icons/file.png'))
                self.tree_widget.addTopLevelItem(temp)

    def digui_view(self, name, parent):
        for entry in os.scandir(name):
            if entry.is_dir():
                # 非top结点只需指定父结点即可
                temp = QTreeWidgetItem(parent, [entry.name])
                temp.setIcon(0, QIcon('icons/folder.png'))
                self.digui_view(os.path.join(name, entry.name), temp)
            else:
                temp = QTreeWidgetItem(parent, [entry.name])
                temp.setIcon(0, QIcon('icons/file.png'))

这样一来效果就好多了,现在我们想展示每个文件的修改日期,再进一步修改代码:

def get_f_time(timestamp):
    return datetime.datetime.fromtimestamp(timestamp).strftime("%Y/%m/%d %H:%M")


class ButtonWindow(QWidget):

    def __init__(self):
        super().__init__()
        self.setWindowTitle('测试button')
        self.resize(400, 300)

        self.layout_main = QVBoxLayout()

        self.layout_header = QHBoxLayout()
        self.le_folder_addr = QLineEdit()
        self.btn_view = QPushButton("浏览")
        self.btn_view.clicked.connect(self.view_folder)
        self.layout_header.addWidget(self.le_folder_addr, stretch=1)
        self.layout_header.addWidget(self.btn_view)
        self.layout_main.addLayout(self.layout_header)

        self.tree_widget = QTreeWidget()
        # 设置两列
        self.tree_widget.setColumnCount(2)
        # 两列的标题
        self.tree_widget.setHeaderLabels(["名称", "修改日期"])

        self.layout_main.addWidget(self.tree_widget)

        self.setLayout(self.layout_main)

    def view_folder(self):
        for entry in os.scandir(self.le_folder_addr.text()):
            if entry.is_dir():
                # 这就是为什么QTreeWidgetItem的构造函数都是传入字符串列表
                temp = QTreeWidgetItem([entry.name, get_f_time(entry.stat().st_mtime)])
                temp.setIcon(0, QIcon('icons/folder.png'))
                self.tree_widget.addTopLevelItem(temp)
                self.digui_view(os.path.join(self.le_folder_addr.text(), entry.name), temp)
            else:
                temp = QTreeWidgetItem([entry.name, get_f_time(entry.stat().st_mtime)])
                temp.setIcon(0, QIcon('icons/file.png'))
                self.tree_widget.addTopLevelItem(temp)

    def digui_view(self, name, parent):
        for entry in os.scandir(name):
            if entry.is_dir():
                temp = QTreeWidgetItem(parent, [entry.name, get_f_time(entry.stat().st_mtime)])
                temp.setIcon(0, QIcon('icons/folder.png'))
                self.digui_view(os.path.join(name, entry.name), temp)
            else:
                temp = QTreeWidgetItem(parent, [entry.name, get_f_time(entry.stat().st_mtime)])
                temp.setIcon(0, QIcon('icons/file.png'))

3、QTableWidget

QTableWidget是QTableView的便捷类,提供一个表格视图。表格有行列之说,QTableWidget的行列数可以在实例化的时候指定,也可以通过setRowCount()setColumnCount()来指定,QTableWidget的每个单元格都是一个QTableWidgetItem,通过setItem()来设置单元格。

QTableWidget必须要设置行列数,不然表格内容是不会显示的

更多用法见:QTableWidget详细说明

class ButtonWindow(QWidget):

    def __init__(self):
        super().__init__()
        self.setWindowTitle('测试button')
        self.resize(400, 300)

        self.layout_main = QVBoxLayout()

        # 新建一个QTableWidget并指定5行3列
        self.table_widget = QTableWidget(5, 3)
        # 水平方向上的标题自然就是列标题
        self.table_widget.setHorizontalHeaderLabels(["数学", "语文", "英语"])
        # 行标题
        self.table_widget.setVerticalHeaderLabels(["张三", "李四", "王五", "赵六", "吴起"])

        # 设置item,需要同时指定行列索引,没有捷径,只能一个个单元格的设置
        self.table_widget.setItem(0, 0, QTableWidgetItem("78"))
        self.table_widget.setItem(1, 0, QTableWidgetItem("89"))
        self.table_widget.setItem(2, 0, QTableWidgetItem("56"))
        self.table_widget.setItem(3, 0, QTableWidgetItem("77"))
        self.table_widget.setItem(4, 0, QTableWidgetItem("99"))

        self.layout_main.addWidget(self.table_widget)

        self.setLayout(self.layout_main)

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值