3

一篇文章学会Python PyQt6表格视图和表单布局的使用方法

 2 months ago
source link: https://www.51cto.com/article/783796.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
489dfc13215f335a06b599637c2b6f9d67825a.png

PyQt6是Python中广受欢迎的GUI框架之一,它提供了丰富的控件和布局方式,可以帮助开发者快速构建交互式应用程序。其中,表格视图和表单布局是常用的两种控件和布局方式,本文将详细介绍它们的使用方法、自定义方法、事件处理以及可能遇到的问题。

1. 使用方法

(1)表格视图

表格视图(QTableView)是PyQt6中用于展示二维表格数据的控件,它可以显示多个行和列,并支持各种格式的数据,如文本、数字、日期、图像等。使用表格视图可以方便地展示和编辑数据,常见的应用场景包括数据分析、报表生成、数据录入等。

在PyQt6中创建表格视图非常简单,只需要创建一个QTableView对象,并将数据模型(QAbstractTableModel)设置给它即可。以下是一个简单的示例代码,用于展示一个3行4列的表格:

from PyQt6.QtWidgets import QApplication, QTableView, QAbstractTableModel
import sys

class MyTableModel(QAbstractTableModel):
    def rowCount(self, parent):
        return 3

    def columnCount(self, parent):
        return 4

    def data(self, index, role):
        if role == Qt.DisplayRole:
            return f'({index.row()},{index.column()})'

app = QApplication(sys.argv)
table_view = QTableView()
model = MyTableModel()
table_view.setModel(model)
table_view.show()
sys.exit(app.exec())

在上面的代码中,我们首先定义了一个自定义的数据模型类MyTableModel,它继承自QAbstractTableModel,并实现了rowCount、columnCount和data三个方法。其中,rowCount和columnCount方法分别返回表格的行数和列数,data方法用于获取指定单元格的数据,我们在这个方法中返回一个文本字符串,格式为(行数,列数)。

然后,我们创建了一个QTableView对象table_view,并将数据模型model设置给它。最后,调用show方法显示表格视图,并通过app.exec()进入Qt事件循环,以保证程序能正常运行。

运行上面的代码,会弹出一个包含3行4列的表格视图,如下图所示:

(2)表单布局

表单布局(QFormLayout)是PyQt6中用于展示表单数据的控件,它可以根据需要自动调整控件的大小和位置,并支持多种类型的控件,如标签、文本框、下拉框、复选框等。使用表单布局可以方便地创建各种表单界面,如登录界面、注册界面、配置界面等。

在PyQt6中创建表单布局也非常简单,只需要创建一个QFormLayout对象,并将需要添加的控件对象添加到它的布局中即可。以下是一个简单的示例代码,用于展示一个包含标签、文本框和下拉框的表单:

from PyQt6.QtWidgets import QApplication, QFormLayout, QLineEdit, QLabel, QComboBox
import sys

app = QApplication(sys.argv)
form_layout = QFormLayout()

name_label = QLabel('姓名:')
name_edit = QLineEdit()
form_layout.addRow(name_label, name_edit)

gender_label = QLabel('性别:')
gender_combobox = QComboBox()
gender_combobox.addItems(['男', '女'])
form_layout.addRow(gender_label, gender_combobox)

form_layout.setFormAlignment(Qt.AlignCenter)
form_layout.setLabelAlignment(Qt.AlignRight)

form_layoutWidget = QWidget()
form_layoutWidget.setLayout(form_layout)
form_layoutWidget.show()
sys.exit(app.exec())

在上面的代码中,我们创建了一个QFormLayout对象form_layout,并向它的布局中添加了一个标签、一个文本框和一个下拉框。其中,标签和文本框通过addRow方法添加到了同一行中,下拉框则添加到了下一行中。我们还使用了setFormAlignment方法和setLabelAlignment方法设置了表单和标签的对齐方式,以保证界面布局的美观。

最后,我们将表单布局添加到一个QWidget对象中,并调用show方法显示界面。运行上面的代码,会弹出一个包含标签、文本框和下拉框的表单,如下图所示:

2. 自定义方法

(1)表格视图

在表格视图中,我们可以通过自定义数据模型类的方法来实现各种功能。以下是一些常用的方法:

  • headerData(section: int, orientation: Qt.Orientation, role: int) -> Any:用于设置表格的行头和列头数据。其中,section参数表示行数或列数,orientation参数表示方向(水平或垂直),role参数表示数据的角色(如显示、编辑、字体等)。
  • setData(index: QModelIndex, value: Any, role: int) -> bool:用于设置指定单元格的数据。其中,index参数表示单元格的索引,value参数表示要设置的数据,role参数表示数据的角色(如显示、编辑、字体等)。
  • flags(index: QModelIndex) -> Qt.ItemFlags:用于设置指定单元格的标志位。其中,index参数表示单元格的索引,Qt.ItemFlags表示单元格的标志位(如是否可编辑、是否可选中等)。
  • rowCount(parent: QModelIndex = QModelIndex()) -> int:用于获取表格的行数。其中,parent参数表示父节点的索引,如果是根节点则返回0。
  • columnCount(parent: QModelIndex = QModelIndex()) -> int:用于获取表格的列数。其中,parent参数表示父节点的索引,如果是根节点则返回0。
  • index(row: int, column: int, parent: QModelIndex = QModelIndex()) -> QModelIndex:用于获取指定单元格的索引。其中,row和column参数分别表示行数和列数,parent参数表示父节点的索引,如果是根节点则返回QModelIndex()。

以下是一个示例代码,用于自定义数据模型类并实现上述方法:

from PyQt6.QtCore import Qt, QAbstractTableModel

class MyTableModel(QAbstractTableModel):
    def __init__(self, data):
        super().__init__()
        self._data = data

    def rowCount(self, parent):
        return len(self._data)

    def columnCount(self, parent):
        return len(self._data[0])

    def data(self, index, role):
        if role == Qt.DisplayRole:
            return str(self._data[index.row()][index.column()])
        return None

    def setData(self, index, value, role):
        if role == Qt.EditRole:
            self._data[index.row()][index.column()] = value
            self.dataChanged.emit(index, index, [Qt.DisplayRole])
            return True
        return False

    def flags(self, index):
        return super().flags(index) | Qt.ItemIsEditable

在上面的代码中,我们定义了一个自定义的数据模型类MyTableModel,它继承自QAbstractTableModel,并实现了rowCount、columnCount、data、setData和flags五个方法。其中,setData方法用于设置单元格数据,flags方法用于设置单元格标志位,以保证表格可以编辑。

(2)表单布局

在表单布局中,我们可以通过添加自定义控件来实现各种功能。以下是一些常用的方法:

  • addRow(label: Union[str, QWidget], field: QWidget) -> None:用于向表单布局中添加一个标签和一个字段组合。其中,label参数可以是文本字符串或控件对象,field参数为字段控件对象。
  • setWidget(row: int, col: int, widget: QWidget) -> None:用于在指定位置设置控件。其中,row和col参数分别表示行数和列数,widget参数为控件对象。
  • insertRow(row: int, label: Union[str, QWidget], field: QWidget) -> None:用于在指定行之前添加一个标签和一个字段组合。其中,row参数表示行数,label参数可以是文本字符串或控件对象,field参数为字段控件对象。
  • removeRow(row: int) -> None:用于删除指定行的标签和字段组合。其中,row参数表示行数。

以下是一个示例代码,用于向表单布局中添加自定义控件:

from PyQt6.QtWidgets import QApplication, QFormLayout, QLineEdit, QLabel, QPushButton
import sys

app = QApplication(sys.argv)
form_layout = QFormLayout()

name_label = QLabel('姓名:')
name_edit = QLineEdit()
form_layout.addRow(name_label, name_edit)

button = QPushButton('确定')
form_layout.setWidget(1, QFormLayout.FieldRole, button)

form_layoutWidget = QWidget()
form_layoutWidget.setLayout(form_layout)
form_layoutWidget.show()
sys.exit(app.exec())

在上面的代码中,我们向表单布局中添加了一个标签和一个文本框,并在第二行的字段位置添加了一个按钮。我们使用了setWidget方法将按钮添加到布局中,并将它的位置设置为(1, QFormLayout.FieldRole),表示在第二行的字段位置。

运行上面的代码,会弹出一个包含标签、文本框和按钮的表单,如下图所示:

3. 事件处理

(1) 表格视图

在表格视图中,我们可以通过重载事件处理方法来处理各种事件。以下是一些常用的事件处理方法:

  • mousePressEvent(event: QMouseEvent) -> None:用于处理鼠标按下事件。其中,event参数为鼠标事件对象。
  • mouseReleaseEvent(event: QMouseEvent) -> None:用于处理鼠标释放事件。其中,event参数为鼠标事件对象。
  • mouseDoubleClickEvent(event: QMouseEvent) -> None:用于处理鼠标双击事件。其中,event参数为鼠标事件对象。
  • keyPressEvent(event: QKeyEvent) -> None:用于处理键盘按下事件。其中,event参数为键盘事件对象。

以下是一个示例代码,用于处理表格视图中的鼠标事件:

from PyQt6.QtWidgets import QApplication, QTableView, QAbstractTableModel
from PyQt6.QtCore import Qt
import sys

class MyTableModel(QAbstractTableModel):
    def rowCount(self, parent):
        return 3

    def columnCount(self, parent):
        return 4

    def data(self, index, role):
        if role == Qt.DisplayRole:
            return f'({index.row()},{index.column()})'

app = QApplication(sys.argv)
table_view = QTableView()
model = MyTableModel()
table_view.setModel(model)

def on_table_view_clicked(index):
    print(f'Clicked: ({index.row()},{index.column()})')

def on_table_view_double_clicked(index):
    print(f'Double clicked: ({index.row()},{index.column()})')

table_view.clicked.connect(on_table_view_clicked)
table_view.doubleClicked.connect(on_table_view_double_clicked)

table_view.show()
sys.exit(app.exec())

在上面的代码中,我们定义了两个事件处理函数on_table_view_clicked和
on_table_view_double_clicked,分别用于处理单击和双击事件。我们通过clicked和doubleClicked信号将这两个函数与表格视图的事件绑定起来,并在事件处理函数中打印出单击或双击的单元格索引。

运行上面的代码,点击或双击表格视图中的单元格,会在控制台输出对应的行列索引,如下图所示:

(2)表单布局

在表单布局中,我们可以通过重载事件处理方法来处理各种事件。以下是一些常用的事件处理方法:

  • mousePressEvent(event: QMouseEvent) -> None:用于处理鼠标按下事件。其中,event参数为鼠标事件对象。
  • mouseReleaseEvent(event: QMouseEvent) -> None:用于处理鼠标释放事件。其中,event参数为鼠标事件对象。
  • mouseDoubleClickEvent(event: QMouseEvent) -> None:用于处理鼠标双击事件。其中,event参数为鼠标事件对象。
  • keyPressEvent(event: QKeyEvent) -> None:用于处理键盘按下事件。其中,event参数为键盘事件对象。

以下是一个示例代码,用于处理表单布局中的鼠标事件:

from PyQt6.QtWidgets import QApplication, QFormLayout, QWidget, QLineEdit, QLabel
from PyQt6.QtCore import Qt
import sys

class MyFormLayout(QFormLayout):
    def __init__(self, parent=None):
        super().__init__(parent)

        name_label = QLabel('姓名:')
        self.name_edit = QLineEdit()
        self.addRow(name_label, self.name_edit)

    def mousePressEvent(self, event):
        if event.button() == Qt.MouseButton.LeftButton:
            print('Left button clicked')
        elif event.button() == Qt.MouseButton.RightButton:
            print('Right button clicked')

app = QApplication(sys.argv)
form_layout = MyFormLayout()

form_layout_widget = QWidget()
form_layout_widget.setLayout(form_layout)
form_layout_widget.show()

sys.exit(app.exec())

在上面的代码中,我们定义了一个继承自QFormLayout的子类MyFormLayout,并重载了mousePressEvent方法,用于处理鼠标按下事件。我们在构造函数中向表单布局中添加了一个标签和一个文本框,并将表单布局放置在一个窗口部件中。

运行上面的代码,点击或右键点击表单布局中的任意位置,会在控制台输出对应的信息,如下图所示:

本文介绍了PyQt6中常用的两种布局方式,即表格视图和表单布局,并介绍了如何使用PyQt6中的事件处理机制处理鼠标和键盘事件。希望这篇文章能够帮助你更好地理解PyQt6的布局和事件处理机制,并能够编写出更加灵活和强大的PyQt6程序。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK