PyQt学习——day4

删除机制

  1. 需要先找到一个节点,可以创建一个list自己来管理;也可以通过findChild、findChildren来查找
  2. 利用deleteLater来删除,注意这个删除是在回到主循环后才执行的,可以理解成释放一个信号
# deleteDemo.py
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *


class Demo(QWidget):
    def __init__(self):
        super(Demo, self).__init__()
        self.__setttingWindow()
        self.__buildUI()

        self.count = 0

    # ================== 功能函数 ==================
    def __setttingWindow(self):
        self.resize(640, 480)

    def __buildUI(self):
        grid = QGridLayout(self)

        # 创建几个标签
        for i in range(4):
            label = QLabel(f"label-{i}")
            grid.addWidget(label, 0, i)

        # 创建一个删除按钮
        btn = QPushButton("删除", clicked=self.do_deleteLabel)
        grid.addWidget(btn, 1, 0)

        btn = QPushButton("增加", clicked=self.do_addLabel)
        grid.addWidget(btn, 1, 1)

    # ================== 槽函数 ==================
    def do_deleteLabel(self):
        label = self.findChild(QLabel)
        if label is None:
            print("删完了")
        else:
            label.deleteLater()

    def do_addLabel(self):
        layout = self.layout()
        label = QLabel(f"newlabel-{self.count}")
        layout.addWidget(label, 0, self.count)
        self.count = (self.count + 1) % 4


if __name__ == '__main__':
    app = QApplication([])
    w = Demo()
    w.show()
    app.exec_()

可重入和线程安全

函数可重入(reentrant):在多个线程上各自创建实例,各个调用同一个函数是安全的;
函数线程安全(thread-safe):多个线程调用同一个实例的同一个函数是安全的;

列表组件

QListWidget

定位:item、row两者也可以互相转换
增加:addItem()、addItems()、insertItem()
删除:takeItem()
常用signal:currentRowChanged
注意:创建空的listWidget时,currentRow是-1;而当加入item(非空)后,会设置currentItem为0,触发一次currentRowChanged

from PyQt5.QtWidgets import *
from PyQt5.QtCore import *


class Demo(QWidget):
    def __init__(self):
        super(Demo, self).__init__()

        self.__setttingWindow()
        self.__buildUI()

    # ================== 功能函数 ==================
    def __setttingWindow(self):
        self.resize(640, 480)

    def __buildUI(self):
        grid = QGridLayout(self)

        # 左边的listWidgets
        self.listNames = QListWidget()
        print(self.listNames.currentRow())
        grid.addWidget(self.listNames, 0, 0, 1, 2)
        self.listNames.addItems(["小红", "小明", "小呆"])
        self.listNames.currentRowChanged.connect(self.do_currentChanged)

        # 按钮组
        grid.addWidget(QPushButton("增加", clicked=self.do_addItem), 1, 0)
        grid.addWidget(QPushButton("删除", clicked=self.do_deleteItem), 1, 1)

    # ================== 槽函数 ==================
    def do_addItem(self):
        # 在末尾增加一个
        self.listNames.addItem("新增名字")
        # self.listNames.setCurrentRow(self.listNames.count() - 1)

    def do_deleteItem(self):
        row = self.listNames.currentRow()
        if row >= 0:
            self.listNames.takeItem(row)

    def do_currentChanged(self, currentRow):
        print(f"现在的行是: {currentRow}")


if __name__ == '__main__':
    app = QApplication([])
    w = Demo()
    w.show()
    app.exec_()

QTableWidget

创建并设置行列:QTableWidget(3, 3)
设置表头:setHorizontalHeaderLabels()
增加:setRowCount(),新建缺失的行,老的行不变
删除:removeRow()删除指定行;setRowCount()删除多余行

from PyQt5.QtWidgets import *
from PyQt5.QtCore import *


class Demo(QWidget):
    def __init__(self):
        super(Demo, self).__init__()

        self.__setttingWindow()
        self.__buildUI()

    # ================== 功能函数 ==================
    def __setttingWindow(self):
        self.resize(640, 480)

    def __buildUI(self):
        grid = QGridLayout(self)

        # 正上方放表格
        self.tableSchools = QTableWidget(3, 3)
        grid.addWidget(self.tableSchools, 0, 0, 1, 2)
        # 表头
        self.tableSchools.setHorizontalHeaderLabels(['名字', '位置', '人数'])
        self.tableSchools.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)

        # 按钮组
        grid.addWidget(QPushButton("增加", clicked=self.do_addRow), 1, 0)
        grid.addWidget(QPushButton("删除", clicked=self.do_deleteRow), 1, 1)

    # ================== 槽函数 ==================
    def do_addRow(self):
        self.tableSchools.setRowCount(self.tableSchools.rowCount() + 1)

    def do_deleteRow(self):
        curRow = self.tableSchools.currentRow()
        if curRow >= 0:
            self.tableSchools.removeRow(curRow)


if __name__ == '__main__':
    app = QApplication([])
    w = Demo()
    w.show()
    app.exec_()

QTreeWidget

创建:QTreeWidget()
设置列数:setColumnCount(2) + setHeaderLabels(['概况', '详细'])
创建顶层节点:topItem = QTreeWidgetItem(self.typeSchool)
设置信息:topItem.setText(0, '人民小学')topItem.setText(1, 'xx省xx市人民小学')
加顶层节点:self.treeSchool.addTopLevelItem(topItem)
加入非顶层节点:利用其父节点,parentItem.addChild(newItem)
删除非顶层节点:利用父节点:curItem.parent().removeChild(curItem)
注意: 引入了type的机制,可以用于描述item的级别;有多个列,设置text时要指定列号;删除、增加都得借助父节点

# treeWidget.demo
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *


class Demo(QWidget):

    typeSchool, typeClass = range(2)

    def __init__(self):
        super(Demo, self).__init__()

        self.__setttingWindow()
        self.__buildUI()

    # ================== 功能函数 ==================
    def __setttingWindow(self):
        self.resize(640, 480)

    def __buildUI(self):
        grid = QGridLayout(self)

        # 左边的treeWidgets
        self.treeSchool = QTreeWidget()
        grid.addWidget(self.treeSchool, 0, 0, 1, 2)
        self.treeSchool.setColumnCount(2)
        self.treeSchool.setHeaderLabels(['概况', '详细'])

        # 创建2个顶层节点
        topItem = QTreeWidgetItem(self.typeSchool)
        topItem.setText(0, '人民小学')
        topItem.setText(1, 'xx省xx市人民小学')
        self.treeSchool.addTopLevelItem(topItem)

        topItem = QTreeWidgetItem(self.typeSchool)
        topItem.setText(0, '憨憨小学')
        topItem.setText(1, 'xx省xx市憨憨小学')
        self.treeSchool.addTopLevelItem(topItem)


        # 按钮组
        grid.addWidget(QPushButton("增加", clicked=self.do_addItem), 1, 0)
        grid.addWidget(QPushButton("删除", clicked=self.do_deleteItem), 1, 1)

    # ================== 槽函数 ==================
    def do_addItem(self):
        # 在顶层节点下增加
        parentItem = self.treeSchool.currentItem()
        if parentItem.type() == self.typeClass:
            parentItem = parentItem.parent()

        newItem = QTreeWidgetItem(self.typeClass)
        newItem.setText(0, '分校')
        newItem.setText(1, f'{parentItem.data(0, Qt.DisplayRole)}的分校')
        parentItem.addChild(newItem)

    def do_deleteItem(self):
        curItem = self.treeSchool.currentItem()
        if curItem.type() == self.typeSchool:
            return

        # curItem.deleteLater()
        curItem.parent().removeChild(curItem)

    def do_currentChanged(self, currentRow):
        # print(f"现在的行是: {currentRow}")
        pass

if __name__ == '__main__':
    app = QApplication([])
    w = Demo()
    w.show()
    app.exec_()

感觉三个组件由于形式差距大,导致API也差得比较多;开始时可以结合其表现形式来熟悉各个函数的使用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值