Pyside6百练成真(12)

QTableWidget

from PySide6.QtCore import Qt
from PySide6.QtWidgets import (QWidget, QApplication, QTabWidget, QTableWidgetItem, QVBoxLayout, QTableWidget)
from faker import Faker
class MyWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.fake = Faker(locale='zh_CN')
        self.resize(800,600)

        self.data = [[self.fake.name(),self.fake.address(),self.fake.ascii_email()] for _ in range(80)]
        self.table = QTableWidget()
        self.table.setRowCount(80)
        self.table.setColumnCount(3)

        for rowIndex,row in enumerate(self.data):
            for columnIndex,item in enumerate(row):
                self.table.setItem(rowIndex,columnIndex,QTableWidgetItem(item))

        self.table.setItem(0,0,QTableWidgetItem(self.fake.name()))

        self.mainLayout = QVBoxLayout()
        self.mainLayout.addWidget(self.table)
        self.setLayout(self.mainLayout)


if __name__ == '__main__':
    app = QApplication([])
    try:
        window = MyWindow()
        window.show()
    except FileNotFoundError as e:
        print(e)
    except RuntimeError as e:
        print(f"Error loading UI: {e}")

    app.exec()
# 设置表头
        self.table.setHorizontalHeaderLabels(['姓名','地址','邮箱'])
        # 设置伸缩样式
        self.table.horizontalHeader().setSectionResizeMode(QHeaderView.ResizeMode.Stretch)

```![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/19a294a2c66e4592b318ce0feca73685.png)
![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/d5c4340b357e4547b9080fbb7a73234a.png)
修改元素:
```python
self.table.item(0,0).setText('666') # 修改

排序

self.table.setSortingEnabled(True)

常用的信号:
在这里插入图片描述
在这里插入图片描述

self.table.cellClicked.connect(lambda row,col:print(f'当前点击了{row}行,第{col}列'))

# 可以添加以恶搞button
self.btn = QPushButton('输出')
self.btn.clicked.connect(self.outputSelect)

def outputSelect(self):
	# print(self.table.selectedItems())
	for i in self.table.selectedItems():
		print(i.text())

在表格中进行搜索:


        # 搜索栏
        self.searchLayout = QHBoxLayout()
        self.lineSearch = QLineEdit()
        self.btnSearch = QPushButton('搜索')
        self.searchLayout.addWidget(self.lineSearch)
        self.searchLayout.addWidget(self.btnSearch)


from PySide6.QtCore import Qt
from PySide6.QtWidgets import (QWidget, QApplication, QTabWidget, QTableWidgetItem, QVBoxLayout, QTableWidget,
                               QHeaderView, QHBoxLayout, QLineEdit, QPushButton)
from faker import Faker
class MyWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.fake = Faker(locale='zh_CN')
        self.resize(800,600)

        # 搜索栏
        self.searchLayout = QHBoxLayout()
        self.lineSearch = QLineEdit()
        self.btnSearch = QPushButton('搜索')
        self.btnSearch.clicked.connect(self.search)

        self.searchLayout.addWidget(self.lineSearch)
        self.searchLayout.addWidget(self.btnSearch)

        self.data = [[self.fake.name(),self.fake.address(),self.fake.ascii_email()] for _ in range(80)]
        self.table = QTableWidget()
        self.table.setRowCount(80)
        self.table.setColumnCount(3)
        # 设置表头
        self.table.setHorizontalHeaderLabels(['姓名','地址','邮箱'])
        # 设置伸缩样式
        self.table.horizontalHeader().setSectionResizeMode(QHeaderView.ResizeMode.Stretch)
        self.table.setSortingEnabled(True)
        self.table.cellClicked.connect(lambda row,col:print(f'当前点击了{row}行,第{col}列'))



        for rowIndex,row in enumerate(self.data):
            for columnIndex,item in enumerate(row):
                self.table.setItem(rowIndex,columnIndex,QTableWidgetItem(item))
        self.table.item(0,0).setText('666') # 修改



        self.table.setItem(0,0,QTableWidgetItem(self.fake.name()))

        self.mainLayout = QVBoxLayout()
        self.mainLayout.addLayout(self.searchLayout)
        self.mainLayout.addWidget(self.table)
        self.setLayout(self.mainLayout)

    def search(self):
        searchContent = self.lineSearch.text()
        for rowIndex, row in enumerate(self.data):
            for columnIndex,item in enumerate(row):
                if searchContent in item:
                    self.table.item(rowIndex,columnIndex).setForeground(Qt.GlobalColor.white)
        result = self.table.findItems(searchContent,Qt.MatchFlag.MatchContains)
        for item in result:
            print(item)
            item.setBackground(Qt.GlobalColor.red)
        #跳转
        self.table.scrollToItem(result[0],QTableWidget.ScrollHint.PositionAtTop)


        # for rowIndex,row in enumerate(self.data):
        #     for columnIndex,item in enumerate(row):
        #         if searchContent in item:
        #             self.table.item(rowIndex,columnIndex).setForeground(Qt.GlobalColor.red)
        #         else:
        #             self.table.item(rowIndex,columnIndex).setBackground(Qt.GlobalColor.yellow)

if __name__ == '__main__':
    app = QApplication([])
    try:
        window = MyWindow()
        window.show()
    except FileNotFoundError as e:
        print(e)
    except RuntimeError as e:
        print(f"Error loading UI: {e}")

    app.exec()

合并单元格
一般用pandas
在这里插入图片描述
QTableWidget的上下文菜单
右键菜单

self.getSelected,triggered.connect(self.outputSelect)
self.table.setContextMenuPolicy(Qt.ContextPolicy.ActionsContextMenu)
self.table.addAction(self.getSelected)

如何加载上万条数据同时保证页面不卡?
分页

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

QTableView

在这里插入图片描述

from PySide6.QtCore import Qt
from PySide6.QtWidgets import (QWidget, QApplication, QTabWidget, QTableWidgetItem, QVBoxLayout, QTableWidget,
                               QHeaderView, QHBoxLayout, QLineEdit, QPushButton, QTableView)
from PySide6.QtGui import QStandardItemModel, QStandardItem
from faker import Faker
class MyWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.fake = Faker(locale='zh_CN')
        self.resize(800,600)
        self.data = [[self.fake.name(),self.fake.phone_number(),self.fake.address()] for _ in range(100)]

        # 创建模型
        self.model = QStandardItemModel()
        for indexRow,row in enumerate(self.data):
            for indexColumn,column in enumerate(row):
                self.model.setItem(indexRow,indexColumn,QStandardItem(column))

        # 创建视图层
        self.table = QTableView()
        self.table.setModel(self.model)

        self.table2 = QTableView()
        self.table2.setModel(self.model)


        self.mainLayout = QVBoxLayout()
        self.mainLayout.addWidget(self.table)
        self.mainLayout.addWidget(self.table2)
        self.setLayout(self.mainLayout)



if __name__ == '__main__':
    app = QApplication([])
    try:
        window = MyWindow()
        window.show()
    except FileNotFoundError as e:
        print(e)
    except RuntimeError as e:
        print(f"Error loading UI: {e}")

    app.exec()

MVC 视图模式:
下面这段代码纯粹的封装继承多态:

# 实现一个简单的MVC框架
#Model层
class Model:
    def __init__(self):
        self.username = None
        self.password = None

    def setUsername(self, username):
        self.username = username

    def setPassword(self, password):
        self.password = password

# view层
class QTableView:
    def __init__(self):
        self.model = None

    def set_model(self, model):
        self.model = model

    def get_model(self):
        return self.model

    def print_model(self):
        print('当前的模型为: ',self.model)
        print(self.model.username,self.model.password)



# 实际应用中,使用下面的代码进行MVC框架的调用
model = Model()
model.setUsername('admin')
model.setPassword('123456')

view = QTableView()
view.set_model(model)
view.print_model()

print(vars(model).items())

QTableView本身的属性
在这里插入图片描述
表头自适应
在这里插入图片描述
排序:

self.table.setSortingEnabled(True)

合并:

self.table.setSpan(0,0,2,2)

表格过滤:
涉及到代理类:

from PySide6.QtCore import Qt, QSortFilterProxyModel
 # 创建一个代理模型
        self.agentModel = QSortFilterProxyModel(self)
        self.agentModel.setSourceModel(self.model)
        self.agentModel.setFilterKeyColumn(-1) # 给所有的列都进行搜索
def bind(self):
	self.searchLineEdit.textChanged.connect(lambda text: self.agentModel.setFilterRegularExpression(text))# 搜索默认第一个
# 可以传正则表达式:QRegularExpression(text)
	

在这里插入图片描述

QSqlQueryModel 只读模型

生成数据

import sqlite3
import pandas as pd
from faker import Faker
import os

os.chdir(os.path.dirname(__file__))
fake = Faker(locale='zh_CN')
data = pd.DataFrame([{'name':fake.name(), 'address':fake.address(),'email':fake.email()} for _ in range(1000)])
connect = sqlite3.connect('test.db')
data.to_sql('data', connect, if_exists='replace',index=False)

from PySide6.QtCore import Qt, QSortFilterProxyModel
from PySide6.QtSql import QSqlDatabase, QSqlQueryModel
from PySide6.QtWidgets import (QWidget, QApplication, QTabWidget, QTableWidgetItem, QVBoxLayout, QTableWidget,
                               QHeaderView, QHBoxLayout, QLineEdit, QPushButton, QTableView)
from PySide6.QtGui import QStandardItemModel, QStandardItem
from faker import Faker
class MyWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle('QSqlQueryModel')
        self.resize(800,600)

        self.table = QTableView()

        # 和数据库建立练习
        self.db = QSqlDatabase.addDatabase('QSQLITE')
        self.db.setDatabaseName('./test.db')
        if not self.db.open():
            raise Exception('数据库打开失败')

        # 创建模型
        self.model = QSqlQueryModel(self)
        self.model.setQuery("select * from user")

        # 创建表格视图
        self.table = QTableView()
        self.table.setModel(self.model)

        self.mainLayout = QVBoxLayout()
        self.mainLayout.addWidget(self.table)
        self.setLayout(self.mainLayout)




if __name__ == '__main__':
    app = QApplication([])
    try:
        window = MyWindow()
        window.show()
    except FileNotFoundError as e:
        print(e)
    except RuntimeError as e:
        print(f"Error loading UI: {e}")

    app.exec()

QSqlTableModel 可以读写的模型
1.导入模型: QSqlTableModel

# 创建模型
self.model = QSqlTableModel()
self.model.setTable("user")#设置具体的表
self.model.select()

修改表头
在这里插入图片描述
在这里插入图片描述

QTabWidget 选项卡

from PySide6.QtWidgets import (QWidget, QApplication, QVBoxLayout, QTableWidget,
                               QLineEdit, QPushButton, QTableView, QLabel, QTabWidget)
from PySide6.QtGui import QStandardItemModel, QStandardItem
from faker import Faker
class MyWindow(QWidget):
    def __init__(self):
        super().__init__()

        self.tab1 = QWidget()
        self.tab1Layout = QVBoxLayout()
        self.tab1Layout.addWidget(QPushButton('按钮1'))
        self.tab1Layout.addWidget(QLabel('标签1'))
        self.tab1.setLayout(self.tab1Layout)

        self.tab2 = QWidget()
        self.tab2Layout = QVBoxLayout()
        self.tab2Layout.addWidget(QPushButton('按钮2'))
        self.tab2Layout.addWidget(QLabel('标签2'))
        self.tab2.setLayout(self.tab2Layout)

        self.tab3 = QWidget()
        self.tab3Layout = QVBoxLayout()
        self.tab3Layout.addWidget(QPushButton('按钮3'))
        self.tab3Layout.addWidget(QLabel('标签3'))
        self.tab3.setLayout(self.tab3Layout)

        self.tab = QTabWidget(self)
        self.tab.addTab(self.tab1,'选项卡1')
        self.tab.addTab(self.tab2,'选项卡2')
        self.tab.addTab(self.tab3,'选项卡3')
        self.tab.setTabsClosable(True)
        # self.tab.setTabShape(QTabWidget.TabShape.Triangular)
        self.tab.setMovable(True)

        self.tab.tabCloseRequested.connect(lambda index:self.tab.removeTab(index))


        self.mainLayout = QVBoxLayout()
        self.mainLayout.addWidget(self.tab)
        self.setLayout(self.mainLayout)


if __name__ == '__main__':
    app = QApplication([])
    try:
        window = MyWindow()
        window.show()
    except FileNotFoundError as e:
        print(e)
    except RuntimeError as e:
        print(f"Error loading UI: {e}")

    app.exec()

在这里插入图片描述

QTimer 计时器,一个不停唠叨的老妈

轮播图: 随着时间不停更换图片
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
QApplication.processEvents()
无论你正在做什么,当你执行到这一条命令的时候,它会把我们现在这个窗体的控制权还给我们的窗体,会卡住
在这里插入图片描述
但是不是真正的多线程是一个伪多线程,只是将控制权暂时交给我们的窗体,让用户能够进行一个操作。

QThread 子类化
子线程如何传递参数给主窗口,说明信号从子窗口发出
在这里插入图片描述

import time

from PySide6.QtCore import Signal, QThread
from PySide6.QtWidgets import (QWidget, QApplication, QLabel, QVBoxLayout)

class WorkThread(QThread):
    signal = Signal(str)

    def __init__(self):
        super().__init__()
        print('run')

    def run(self):
        for i in range(1,10):
            self.signal.emit(str(i))
            time.sleep(1)

class MyWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.lb = QLabel('当前的值为:0')
        self.workThread = WorkThread()
        self.workThread.signal.connect(lambda x:self.lb.setText(f'当前的值为:'+x))
        self.workThread.started.connect(lambda :print('线程开始'))
        self.workThread.finished.connect(lambda :print('线程结束'))
        self.workThread.start()

        self.mainLayout = QVBoxLayout()
        self.mainLayout.addWidget(self.lb)
        self.setLayout(self.mainLayout)




if __name__ == '__main__':
    app = QApplication([])
    try:
        window = MyWindow()
        window.show()
    except FileNotFoundError as e:
        print(e)
    except RuntimeError as e:
        print(f"Error loading UI: {e}")

    app.exec()

在这里插入图片描述

实例化创建多线程
在这里插入图片描述

主线程传递给子线程
在这里插入图片描述

阻塞线程
wait()

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值