常用控件2

组合选择框

QComboBox 是组合选择框,如下图所示

image

官网介绍

信号:选项改变

如果用户操作修改了QComboBox中的选项就会发出 currentIndexChanged 信号,可以这样指定处理该信号的函数

cbox.currentIndexChanged.connect(handleSelectionChange)

添加一个选项

代码中可以使用 addItem 方法来添加一个选项到 末尾 ,参数就是选项文本

cbox.addItem('byhy')

添加多个选项

代码中可以使用 addItems 方法来添加多个选项到 末尾,参数是包含了多个选项文本的列表

cbox.addItems(['byhy','白月黑羽','python教程'])

清空选项

代码中可以使用 clear 方法来清空选项,也就是删除选择框内所有的选项

cbox.clear()

获取当前选项文本

代码中可以使用 currentText 方法来获取当前 选中的选项 的文本,比如

method = cbox.currentText()

列表

QListWidget 是列表控件,如下图所示

image

Qt Designer 如下图 选择:

image

列表里面每个列表项对应的类型是 QListWidgetItem


QListWidget 官网介绍

QListWidgetItem 官网介绍

实例化

可以通过Qt设计师创建UI,然后加载界面的方式实例化。

也可以直接通过代码创建列表控件实例

from PySide2 import  QtWidgets

# parent变量对应的是父控件对象
listWidget = QtWidgets.QListWidget(parent)

添加一个列表项

代码中可以使用 addItem 方法来添加一个列表项到 末尾 ,参数就是列表项文本

listWidget.addItem('byhy')

如果你要添加的列表项并非简单的文本,而是,比如有图标

则需要添加参数是一个 QListWidgetItem 实例

# 创建QListWidgetItem实例
listItem = QListWidgetItem()

# 设置图标
listItem.setIcon(some_icon)

# 可以给该列表项关联任意的对象
listItem.deviceCtrl = deviceCtrl

# 添加到列表控件中
listWidget.addItem(listItem)

添加多个列表项

代码中可以使用 addItems 方法来添加多个列表项到 末尾,参数是包含了多个列表项文本的列表

listWidget.addItems(['byhy','白月黑羽','python教程'])

删除一个列表项

代码中可以使用 takeItem 方法来删除1个列表项,参数是该列表项所在行

listWidget.takeItem(1)

就会删除第二行列表项


那,怎么指定某个item是第几行呢?

使用row方法,如下

listWidget.row(item)

清空列表项

代码中可以使用 clear 方法来清空列表项,也就是删除选择框内所有的列表项

listWidget.clear()

设置某个列表项为当前列表项

可以通过 setCurrentItem 方法,设置某个列表项为当前列表项

如下

listWidget.setCurrentItem(listItem)

获取当前列表项文本

currentItem 方法可以得到列表当前选中项对象(QListWidgetItem) ,再调用这个对象的 text 方法,就可以获取文本内容,比如

listWidget.currentItem().text()

可以使用 item 方法获取指定某行的 QListWidgetItem,

比如,

listWidget.item(0).text()

就获取了 第1行 的列表项的文本。

遍历列表项

可以这样遍历列表里面的每个item

for i in range(listWidget.count()):
    # 取出列表项
    listItem = listWidget.item(i)

信号:选项选择改变

如果用户鼠标或者键盘选择了一个选项,Qt就会发出 itemSelectionChanged 信号,可以这样指定处理该信号的函数

self.listWidget.itemSelectionChanged.connect(
    self.handleSelectionChange
)

然后定义一个处理函数

    # 设备列表项选择改变 信号处理
    def handleSelectionChange(self):
        # 当前选择项目
        currentItem = self.listWidget.currentItem()

信号:选项文本改变

如果列表项文本可以编辑,并且用户修改了文本,Qt就会发出 itemChanged 信号,可以这样指定处理该信号的函数

self.listWidget.itemChanged.connect(
    self.handleItemTextChange
)

然后定义一个处理函数

    # 设备列表项选择改变 信号处理
    # 参数 item 是修改的   QListWidgetItem对象
    def handleItemTextChange(self, item):
        # 这里写处理代码
        

内参 - 带图标的列表项

添加一个带图标的列表项,就需要创建 QListWidgetItem

如下所示

from PySide2.QtWidgets import QListWidgetItem
from PySide2.QtGui import QIcon
from PySide2.QtCore import QSize

# 列表框设置图标大小,也可以在Qt设计师里面设置
listWidget.setIconSize(QSize(30, 30))

# 先创建图标对象
listIcon = QIcon("icon1.png")

# 创建一个列表项
listItem = QListWidgetItem()
# 设置列表项图标
listItem.setIcon(self.listIcon)
# 设置列表项文本
listItem.setText('byhy')

# 把列表项添加到列表框中
listWidget.addItem(listItem)

内参 - 列表项文本可编辑

要能做到直接双击修改列表项文本,

首先必须设置列表项为 可编辑: ItemIsEditable

可以在创建列表项的时候设置,如下代码所示

from PySide2.QtCore import Qt

listItem = QListWidgetItem()

# 设置图标
listItem.setIcon(someIcon)

# 设置文本内容
listItem.setText('byhy')

# 设置该节点在以前的flag基础上,多一个 ItemIsEditable
listItem.setFlags(listItem.flags()  | Qt.ItemIsEditable)

# 把列表项添加到列表框中
listWidget.addItem(listItem)

# 使列表项处于编辑状态
listWidget.editItem(listItem)  

这样设置好以后,节点被编辑内容后,其所属 QListWidget 就会触发 itemChanged 信号

我们应该定义该信号的处理函数,如下所示


class MainWindow:

    def __init__(self):
     
        # 前面的一些初始化代码
        。。。。

        
        # 如果列表项需要从存档文件内容中加载,必须先加载
        # 然后再设置 itemChanged 信号处理
        # 否则加载过程也会触发 itemChanged 信号
        self.loadList()

        # 设置 itemChanged 信号处理
        self.ui.listWidget.itemChanged.connect(self.itemChanged)

    def itemChanged(self, item):
        # 参数 item 是修改的   QListWidgetItem对象

        # 获取修改后的文本
        newText = item.text(column)

       

如果想程序直接置列表项为编辑状态,只需对列表对象调用 editItem 方法,如下

listWidget.editItem(listItem)

表格

QTableWidget 是表格控件,如下图所示

image

表格控件单元格里面可以显示文字,也可以显示富文本、图片等内容。

表格控件的每个单元格里面要显示内容,都必须创建一个 QTableWidgetItem 类型的对象。

Qt Designer 如下图 选择:

image


官网介绍: QTableWidge

官网介绍: QTableWidgetItem

实例化

可以通过Qt设计师创建UI,然后加载界面的方式实例化。

也可以直接通过代码创建表格控件实例

from PySide2 import  QtWidgets

rows    = 0  # 行数
columns = 2  # 列数

# parent变量对应的是父控件对象
table = QtWidgets.QTableWidget(rows, columns, parent)

创建列 和 标题栏

我们可以通过 Qt designer 为一个表格创建列和对应的标题栏。

只需要双击 Qt designer 设计的窗体中的 表格控件, 就会出现这样的对话框。

image

标签栏中,点击左下角的加号,就可以为 添加一个列,并且设置标题栏名称。

image

插入一行、删除一行

insertRow 方法可以在指定位置插入一行,比如

table.insertRow(0)

就插入一行到第 1 行这个位置, 表格原来第1行(包括原来的第1行)以后的内容,全部往下移动一行。

table.insertRow(2)

就插入一行到第 3 行这个位置, 表格原来第3行(包括原来的第3行)以后的内容,全部往下移动一行。


removeRow 方法可以删除指定位置的一行,比如

table.removeRow(0)

就删除第 1 行, 表格原来第1行以后的内容,全部往上移动一行。

table.removeRow(2)

就删除第 3 行, 表格原来第3行以后的内容,全部往上移动一行。

设置单元格内容、对齐、属性

qt表格的单元格内的内容对象 是一个 单元格对象 QTableWidgetItem 实例

如果单元格 没有被设置过 内容,可以这样

from PySide2.QtWidgets import QTableWidgetItem

item = QTableWidgetItem()
item.setText('白月黑羽')
table.setItem(row, 0, item)

也可以简写为

from PySide2.QtWidgets import QTableWidgetItem

table.setItem(row, 0, QTableWidgetItem('白月黑羽'))

如果单元格 已经被设置过 文本内容,

item 方法可以获取指定位置的 QTableWidgetItem ,再调用这个对象的 setText 方法,就可以设置单元格文本内容,比如

table.item(0,0).setText('白月黑羽-江老师')

就设置了 第1行,第1列 的单元格里面的文本。

table.item(2,4).setText('白月黑羽-江老师')

就设置了 第3行,第5列 的单元格里面的文本。


如果希望某个单元格为 只读,不允许修改,可以使用QTableWidgetItem对象的 setFlags 方法,像这样

from PySide2.QtWidgets import QTableWidgetItem
from PySide2.QtCore import Qt

item = QTableWidgetItem('白月黑羽')
item.setFlags(Qt.ItemIsEnabled) # 参数名字段不允许修改
table.setItem(row, 0, item)

如果想文本内容 居中对齐,每个当对应的QTableWidgetItem 调用 setTextAlignment,如下

from PySide2.QtWidgets import QTableWidgetItem
from PySide2.QtCore import Qt

item = QTableWidgetItem()
item.setText('白月黑羽')
# 文本居中
item.setTextAlignment(Qt.AlignCenter) 
table.setItem(row, 0, item)

如果想设置 表格框 和 单元格边线 的颜色,可以使用样式如下

QTableWidget {
	border:1px solid green;
    gridline-color: rgb(71, 191, 255);
}

获取单元格文本的内容

item 方法可以指定位置的单元格对象(QTableWidgetItem) ,再调用这个对象的 text 方法,就可以获取文本内容,比如

table.item(0,0).text()

就获取了 第1行,第1列 的单元格里面的文本。

table.item(2,4).text()

就获取了 第3行,第5列 的单元格里面的文本。

获取所有行数、列数

代码中可以使用 rowCount 方法来获取表格所有的 行数 ,比如

rowcount = table.rowCount()

可以使用 columnCount 方法来获取表格所有的 列数 ,比如

rowcount = table.columnCount()

获取当前选中是第几行

代码中可以使用 currentRow 方法来获取当前选中是第几行,比如

currentrow = table.currentRow()

注意:行数是从0开始的, 第一行的行数是 0

设置表格行数、列数

代码中可以使用 setRowCount 方法来设置表格 行数 ,比如

table.setRowCount(10)

代码中可以使用 setColumnCount 方法来设置表格 列数 ,比如

table.setColumnCount(10)

清除/删除所有内容

clearContents 方法可以清除表格所有的内容,比如

table.clearContents()

清除后,仍然会留下表格栏


如果连表格栏都要删除,可以使用 setRowCount(0),像这样

table.setRowCount(0)

设定列宽、宽度自动缩放

Qt Designer 上目前没法拖拽设定 每个列的宽度,只能在代码中指定。

如下所示

# 设定第1列的宽度为 180像素
table.setColumnWidth(0, 180)

# 设定第2列的宽度为 100像素
table.setColumnWidth(1, 100)

如想让 表格控件宽度 随着父窗口的缩放自动缩放,可以

在 属性编辑器 中 勾选 HorizontalHeaderStretchLastSection

或者使用下面代码

tableHeader = table.horizontalHeader()
tableHeader.setStretchLastSection(True)

还可以像下面这样设置

信号:单元格内容改动

当用户修改了一个单元格的内容,会发出 cellChanged 信号,并且携带参数指明该单元格的行号和列号。

我们的代码可以对该信号进行相应的处理。

示例代码如下

    def __init__(self):
        # 指定单元格改动信号处理函数
        self.ui.table.cellChanged.connect(self.cfgItemChanged)

    
    def cfgItemChanged(self,row,column):
        # 获取更改内容
        cfgName = self.ui.table.item(row, 0).text() # 首列为配置名称
        cfgValue = self.ui.table.item(row, column).text()

内参 - 代码指定表格标头

可以这样用代码设定表格的水平标头,和 垂直标头

# 水平标头设定
# 标头参数是列表,列表元素都是字符串,依次指定标头
table.setHorizontalHeaderLabels(["属性","值"])

# 垂直标头设定
table.setVerticalHeaderLabels(["数据1","数据2","数据3"])

# 隐藏垂直表头
table.verticalHeader().hide() # 隐藏垂直表头

内参 - 表格样式

如果 想指定 表格控件边线样式 ,可以通过QSS 属性 border 指定

如果 想指定 单元格线颜色 ,可以通过QSS 属性 gridline-color 指定

如下所示

tableStyle = '''QTableWidget {
    border:1px solid green;
    gridline-color: rgb(71, 191, 255);
    background-color: aliceblue; 
}'''

table.setStyleSheet(tableStyle)

border:1px solid green 指定表格边界线颜色为 绿色实线,

gridline-color: rgb(71, 191, 255) 指定单元格边线颜色为浅蓝色

background-color: aliceblue 指定表格背景颜色为蓝灰色


要设置 单元格线样式 为实 线、虚线 等,

可以通过 QT 设计师 gridStyle 属性设置

也可以通过代码设置,如下

from PySide2.QtCore import Qt

table.setGridStyle(Qt.DashLine)

如果希望表格标题栏下面有分割线,可以这样

tableStyle = '''
QTableWidget {
    gridline-color: #e0e0e0;
}
      
QHeaderView::section {     
    background-color: #f8f8f8;
    border-top: 0px solid #e0e0e0;
    border-left: 0px solid #e0e0e0;
    border-right: 1px solid #e0e0e0;
    border-bottom: 1px solid #e0e0e0;
}
'''

table.setStyleSheet(tableStyle)