Clase QStandardItemModel

1. Clases principales:
clase QStandardItemModel

(1) Función: una clase de modelo de datos estándar basada en datos de elementos, que generalmente forma una estructura Modelo / Vista con QTableView para realizar la gestión de datos bidimensionales generales. Cada elemento es un objeto de la clase QStandardItem, que se utiliza para almacenar los datos del elemento, el formato de fuente, la alineación y otros datos de diversas funciones.

Función de clase QTableView
(1): componente de vista de tabla de datos bidimensional, con múltiples filas y múltiples columnas, cada unidad de visualización básica es una celda, después de configurar un modelo de datos de la clase QStandardItemModel a través de la función setModel (), se muestra una celda un elemento en el modelo de datos QStandardItemModel.


Función QItemSelectionModel (1): la clase utilizada para rastrear el estado de selección de celda del componente de vista. Cuando se seleccionan una celda o varias celdas en el componente QTableView, el índice del modelo de la celda seleccionada se puede obtener a través de QItemSelectionModel, que es la celda La operación de selección proporciona comodidad.

Tres tipos de relaciones:
QStandardItemModel es una clase de modelo de datos, QItemSelectionModel necesita configurar un objeto QStandardItemModel como modelo de datos, QTableView es un componente de vista de interfaz, que necesita configurar un objeto QStandardItemModel como modelo de datos. Para lograr operaciones de selección de elementos convenientes, También necesita establecer un objeto de clase QItemSelectionModel como modelo de selección de elementos.

Caso de prueba:
tome la siguiente interfaz de software como ejemplo y
inserte la descripción de la imagen aquí
pruebe las siguientes funciones:
1. Abra un archivo de texto sin formato, que es un archivo de datos bidimensional normal, obtenga los datos del encabezado de la tabla y de cada fila y columna mediante el procesamiento de cadenas. e importar un modelo de datos QStandardItemModel.
2. Edite y modifique los datos del modelo de datos, puede insertar filas, agregar filas, eliminar filas y puede modificar directamente el contenido de los datos de las celdas en el componente de vista QTableView.
3. Puede configurar los datos de diferentes roles de un elemento en el modelo de datos, configurar la alineación del texto, si está en negrita, etc.
4. Obtenga la celda actual en el componente de vista y el rango de la celda seleccionada a través de QItemSelectionModel y opere en la celda seleccionada.
5. Muestre el contenido de datos del modelo de datos en el componente QPlainTextEdit, muestre el contenido del modelo de datos y verifique si la modificación realizada en el componente de vista está sincronizada con el modelo de datos.
6. Guarde los datos del modelo modificado como un archivo de texto.

Uso de QStandardItemModel
1. Inicialización de la interfaz
Copie y cree la plantilla del proyecto mainWindowApp, y el archivo de formulario es MainWindow.ui.
La clave está en la creación de modelos de datos y modelos de selección, así como la asociación con componentes de vista, la asociación de señales y ranuras, etc.

import sys,os
from PyQt5.QtWidgets import  (QApplication, QMainWindow,
                   QLabel, QAbstractItemView, QFileDialog)
from PyQt5.QtCore import  Qt, pyqtSlot,QItemSelectionModel, QModelIndex
from PyQt5.QtGui import QStandardItemModel, QStandardItem
from ui_MainWindow import Ui_MainWindow

class QmyMainWindow(QMainWindow): 
    def __init__(self, parent=None):
      super().__init__(parent)    #调用父类构造函数,创建窗体
      self.ui = Ui_MainWindow()     #创建UI对象
      self.ui.setupUi(self)       #构造UI界面
      self.setCentralWidget(self.ui.splitter)

      self.__ColCount = 6  #列数=6
      self.itemModel = QStandardItemModel(5,self.__ColCount,self)# 数据模型,10行6列

      self.selectionModel = QItemSelectionModel(self.itemModel) #Item选择模型
      self.selectionModel.currentChanged.connect(self.do_curChanged)

      self.__lastColumnTitle="测井取样"
      self.__lastColumnFlags=(Qt.ItemIsSelectable
                              | Qt.ItemIsUserCheckable | Qt.ItemIsEnabled)

      ##tableView设置
      self.ui.tableView.setModel(self.itemModel) #设置数据模型
      self.ui.tableView.setSelectionModel(self.selectionModel)    #设置选择模型

      oneOrMore=QAbstractItemView.ExtendedSelection
      self.ui.tableView.setSelectionMode(oneOrMore) #可多选

      itemOrRow=QAbstractItemView.SelectItems
      self.ui.tableView.setSelectionBehavior(itemOrRow)   #单元格选择
      
      self.ui.tableView.verticalHeader().setDefaultSectionSize(22)#缺省行高
      self.ui.tableView.setAlternatingRowColors(True)   #交替行颜色

      self.ui.tableView.setEnabled(False)  #先禁用tableView
      self.__buildStatusBar()

Cree el modelo de datos (QStandardItemModel) y el modelo de selección (QItemSelectionModel) en el constructor
1. Especifique el número de filas y columnas del modelo de datos al crear el objeto QStandardItemModel
2. Cree el objeto QItemSelectionModel con el objeto QStandardItemModel como parámetro, de modo que que el modelo de datos y el modelo de selección estén establecidos 3.
El constructor también asocia la señal currentChanged() del objeto QItemSelectionModel con la función de ranura personalizada do_curChanged()
4. Establezca el modelo de datos y el modelo de selección para el componente de interfaz, y llame setModel(QStandardItemModel) para establecer una conexión con setSelectionModel(QItemSelectionModel) .
5. Establezca el modo de selección, llame a la función setSelectionMode (enumeración de modo)
6. Cree una barra de estado, llame a la función privada __buildStatusBar()

2. Importar datos desde archivos de texto
Algunos datos se guardan en formato de texto sin formato, tienen un número fijo de columnas y cada columna es un elemento de datos, que en realidad constituye una tabla de datos bidimensional.
inserte la descripción de la imagen aquí
El siguiente es el código de función de ranura para "abrir archivo":

##  ==========由connectSlotsByName() 自动连接的槽函数==================        
   @pyqtSlot()  ##“打开文件”
   def on_actOpen_triggered(self):  
   ##        curPath=QDir.currentPath() #获取当前路径
      curPath=os.getcwd()   #获取当前路径
      
      filename,flt=QFileDialog.getOpenFileName(self,"打开一个文件",curPath,
                  "井斜数据文件(*.txt);;所有文件(*.*)")
      if (filename==""):
         return

      self.LabCurFile.setText("当前文件:"+filename)
      self.ui.plainTextEdit.clear()

      aFile=open(filename,'r')
      allLines=aFile.readlines()  #读取所有行,list类型,每行末尾带有 \n
      aFile.close()

      for strLine in allLines:
         self.ui.plainTextEdit.appendPlainText(strLine.strip())

      self.__iniModelFromStringList(allLines)  
      self.ui.tableView.setEnabled(True)  #tableView可用
      self.ui.actAppend.setEnabled(True)  #更新Actions的enable属性
      self.ui.actInsert.setEnabled(True)
      self.ui.actDelete.setEnabled(True)
      self.ui.actSave.setEnabled(True)
      self.ui.actModelData.setEnabled(True)

1. El módulo os utiliza la función getcwd() para obtener la ruta de trabajo actual ;
2. La clase QFileDialog abre el cuadro de diálogo del archivo a través de getOpenFileName() para seleccionar un archivo y devuelve dos variables, que son el nombre del archivo seleccionado (filename) y filtro de archivos (flt) .
3. Abra el archivo Utilice la función de apertura de archivos integrada de Python open() para abrir el archivo en modo de solo lectura y utilice la función readlines() para leer todo el texto en una lista de cadenas a la vez. Cada línea de la lista tiene un carácter de nueva línea \n.
4. Recorrer la lista, extraer cada línea para mostrar appendPlainText()
5. La función __iniModelFromStringList() es una función privada que inicializa el modelo de datos según el contenido del texto leído.
El código de la función __iniModelFromStringList() es el siguiente:

def __iniModelFromStringList(self,allLines):  ##从字符串列表构建模型
      rowCnt=len(allLines) #文本行数,第1行是标题
      self.itemModel.setRowCount(rowCnt-1) #实际数据行数

      headerText=allLines[0].strip() #第1行是表头,去掉末尾的换行符 "\n"
      headerList=headerText.split("\t")      #转换为字符串列表
      self.itemModel.setHorizontalHeaderLabels(headerList)  #设置表头标题

      self.__lastColumnTitle=headerList[len(headerList)-1] # 最后一列表头的标题,即“测井取样”

      lastColNo=self.__ColCount-1  #最后一列的列号
      for i in range(rowCnt-1):  
         lineText=allLines[i+1].strip()  #一行的文字,\t分隔
         strList=lineText.split("\t")    #分割为字符串列表 
         for j in range(self.__ColCount-1):  #不含最后一列
            item=QStandardItem(strList[j])
            self.itemModel.setItem(i,j,item)  #设置模型的item
             
         item=QStandardItem(self.__lastColumnTitle)  #最后一列
         item.setFlags(self.__lastColumnFlags)
         item.setCheckable(True)
         if (strList[lastColNo]=="0"):
            item.setCheckState(Qt.Unchecked)
         else:
            item.setCheckState(Qt.Checked)

         self.itemModel.setItem(i,lastColNo,item) #设置最后一列的item

1. El parámetro allLines es una lista de cadenas compuesta por todas las líneas del archivo de texto, y cada línea es una cadena de la lista allLines. La primera línea es el texto del encabezado y los datos de la segunda línea.
2. Función len (lista) : para obtener el número de elementos de la lista, es decir, el número de cada línea del texto original.
3. Función setRowCount (número de fila) : para establecer la lista
. 4. Obtener la cadena de encabezado headerText. desde allLines, y luego use la función str.split() divide una cadena en una lista de encabezados de lista de cadenas
5. La función setHorizontalHeaderLabels (lista) de la clase QStandardItemModel : y configúrelo como el título del encabezado del modelo de datos
6. QStandardItemModel guarda el datos del elemento en forma de una tabla bidimensional. Cada elemento es un objeto QStandardItem y cada elemento corresponde a una celda de QTableView. Los datos del elemento no solo pueden almacenar el texto mostrado, sino también los datos de otras funciones.
7. La última columna del archivo de datos es un dato lógico, que proporciona una casilla de verificación cuando se muestra en el componente de interfaz tableView. La función se llama llamando a la implementación de la función QStandardItem setCheckable(True) .
8. La función setFlags(ItemFlags) de QStandardItemSe pueden configurar algunos indicadores del elemento y ItemFlags es una combinación de valores del tipo de enumeración Qt.ItemFlag. Se define una variable privada self.__lastColumnFlags en el constructor de QmyMainWindow para establecer el indicador de la última columna.

3. Modificación de datos
Cuando el componente de la interfaz tableView está configurado como editable, haga doble clic en una celda para modificar su contenido. Para una columna que usa una casilla de verificación, cambie el estado de verificación de la casilla de verificación para modificar los datos del elemento asociado de la célula.

La modificación de datos es para el modelo de datos. Una vez modificado el modelo de datos, se mostrará en la vista de tabla.
Como agregar filas, insertar filas, eliminar filas.

   @pyqtSlot()   ##在最后添加一行
   def on_actAppend_triggered(self):   
      itemlist=[]    # QStandardItem 对象列表
      for i in range(self.__ColCount-1):  #不包括最后一列
         item=QStandardItem("0")
         itemlist.append(item)
         
      item=QStandardItem(self.__lastColumnTitle) #最后一列
      item.setCheckable(True)
      item.setFlags(self.__lastColumnFlags)
      itemlist.append(item)

      self.itemModel.appendRow(itemlist)  #添加一行
      curIndex=self.itemModel.index(self.itemModel.rowCount()-1,0)
      self.selectionModel.clearSelection()
      self.selectionModel.setCurrentIndex(curIndex,QItemSelectionModel.Select)

   @pyqtSlot()  ##插入一行
   def on_actInsert_triggered(self):   
      itemlist=[]  #  QStandardItem 对象列表
      for i in range(self.__ColCount-1): #不包括最后一列
         item=QStandardItem("0")
         itemlist.append(item)
         
      item=QStandardItem(self.__lastColumnTitle) #最后一列
      item.setFlags(self.__lastColumnFlags)
      item.setCheckable(True)
      item.setCheckState(Qt.Checked)
      itemlist.append(item)

      curIndex=self.selectionModel.currentIndex(); #获取当前选中项的模型索引
      self.itemModel.insertRow(curIndex.row(),itemlist);  #在当前行的前面插入一行
      self.selectionModel.clearSelection()
      self.selectionModel.setCurrentIndex(curIndex,QItemSelectionModel.Select)
        

   @pyqtSlot()   ##删除当前行
   def on_actDelete_triggered(self): 
      curIndex=self.selectionModel.currentIndex()  #获取当前选择单元格的模型索引
      self.itemModel.removeRow(curIndex.row())     #删除当前行

(1) Agregar una línea
equivale a agregar un elemento inicializado a la última línea de la lista, que puede ser 0 o estar marcado. Cada elemento en la última línea forma una lista de elementos, use la función appendRow() de QStandardItemModel para agregar una línea al final del
prototipo de función del modelo de datos appendRow(self, items)

Los elementos del parámetro son una lista de tipo QStandardItem, y se debe crear un objeto de tipo QStandardItem para cada elemento de la fila agregada y luego pasarlo a la función appendRow().

Para obtener el índice del modelo de una celda en QStandardItemModel, use su función index() . En el programa, obtenga el índice del modelo de la celda pasando sus números de fila y columna.

Para seleccionar un elemento a través del programa, utilice el método correspondiente del modelo de selección QItemSelectionModel, y la operación de selección se reflejará en el componente de interfaz asociado tableView a tiempo. Las funciones **clearSelection() y setCurrentIndex()** de la clase QItemSelectionModel se utilizan aquí para completar las funciones de borrar la selección y configurar la primera columna de la fila recién insertada que se seleccionará.
(2) Insertar fila
La función del botón "Insertar fila" es insertar una fila antes de la fila actual, y su código de implementación es similar al de "Agregar fila".

Utilice la función insertRow() de QStandardItemModel para insertar un
prototipo de función de fila insertRow(self, row, items)

La fila del parámetro es un número de fila, lo que significa insertar una fila antes de la fila de este número de fila. Si la fila es igual o mayor que el número total de filas, se agregará una fila al final. items es una lista de tipo QStandardItem.
(3) Eliminar fila
La función del botón "Eliminar fila" es eliminar la fila actual. Primero, obtenga el índice del modelo de la celda actual del modelo de selección, luego obtenga el número de fila del índice del modelo y llame al Función removeRow(fila) para eliminar la fila especificada .

4. Configuración del formato de celda
Cada elemento en el modelo de datos del elemento es un objeto QStandardItem QStandardItem proporciona algunas funciones de interfaz para configurar la fuente, el color de fondo, el color de primer plano, la alineación del texto, el icono, etc.

Este ejemplo ilustra el formato del modelo de datos del elemento con alineación de texto y configuración en negrita.

   def  __setCellAlignment(self, align=Qt.AlignHCenter):
      if (not self.selectionModel.hasSelection()): #没有选择的项
         return
      selectedIndex=self.selectionModel.selectedIndexes()  #模型索引列表
      count=len(selectedIndex)
      for i in range(count):
         index=selectedIndex[i]  #获取其中的一个模型索引
         item=self.itemModel.itemFromIndex(index)    #获取一个单元格的项数据对象
         item.setTextAlignment(align) #设置文字对齐方式
   
   @pyqtSlot()    ##左对齐
   def on_actAlignLeft_triggered(self):  
      self.__setCellAlignment(Qt.AlignLeft | Qt.AlignVCenter)

   @pyqtSlot()    ##中间对齐
   def on_actAlignCenter_triggered(self):  
      self.__setCellAlignment(Qt.AlignHCenter| Qt.AlignVCenter)
        
   @pyqtSlot()    ##右对齐
   def on_actAlignRight_triggered(self):   
      self.__setCellAlignment(Qt.AlignRight | Qt.AlignVCenter)

   @pyqtSlot(bool)   ##字体Bold
   def on_actFontBold_triggered(self,checked):
      if (not self.selectionModel.hasSelection()): #没有选择的项
         return
      selectedIndex=self.selectionModel.selectedIndexes()   #模型索引列表
      count=len(selectedIndex)
      for i in range(count):
         index=selectedIndex[i]     #获取其中的一个模型索引
         item=self.itemModel.itemFromIndex(index)    #获取一个单元格的项数据对象
         font=item.font()
         font.setBold(checked)
         item.setFont(font)

Los tres códigos de acción que establecen la alineación llaman a la **función privada personalizada __setCellAlignment()** en la que se utilizan las siguientes dos funciones de QItemSelectionModel.

Función hasSelection() : devuelve un valor bool que indica si hay una celda seleccionada.

Función selectedIndexes () : devuelve una lista cuyos elementos son de tipo QModelIndex, incluidos los índices del modelo de todas las celdas seleccionadas. Cuando el componente de interfaz tableView está configurado en selección múltiple, se pueden seleccionar varias celdas.

Utilice la función itemFromIndex(index) de la clase QStandardItemModel para devolver el objeto QStandardItem cuyo índice de modelo es index.

5. Guarde los datos como un archivo.
La modificación de datos en el componente de vista se actualizará automáticamente al modelo de datos. Haga clic en el botón "Datos del modelo" en la barra de herramientas para mostrar el contenido de datos del modelo de datos en el componente PlainTextEdit en la lado derecho del formulario

   @pyqtSlot()    ##模型数据显示到plainTextEdit里
   def on_actModelData_triggered(self):  
      self.ui.plainTextEdit.clear()
      lineStr=""
      for i in range(self.itemModel.columnCount()-1):  #表头,不含最后一列
         item=self.itemModel.horizontalHeaderItem(i)
         lineStr=lineStr+item.text()+"\t"
      item=self.itemModel.horizontalHeaderItem(self.__ColCount-1) #最后一列
      lineStr=lineStr+item.text()   #表头文字字符串
      self.ui.plainTextEdit.appendPlainText(lineStr)

      for i in range(self.itemModel.rowCount()):
         lineStr=""
         for j in range(self.itemModel.columnCount()-1): #不包括最后一列
            item=self.itemModel.item(i,j)
            lineStr=lineStr+item.text()+"\t"
         item=self.itemModel.item(i,self.__ColCount-1) #最后一列
         if (item.checkState()==Qt.Checked):
            lineStr=lineStr+"1"
         else:
            lineStr=lineStr+"0"
         self.ui.plainTextEdit.appendPlainText(lineStr)

Esto implica principalmente la lectura del título del encabezado del modelo de datos del artículo y la lectura del contenido de los datos del artículo línea por línea.

La función horizontalHeaderItem() de QStandardItemModel devuelve un objeto de elemento de datos del encabezado de fila y su prototipo de función es:

horizontalHeaderItem(self, colNo) -> QStandardItem

El parámetro colNo es el número de columna y el valor de retorno es un objeto QStandardItem.

Los títulos de encabezado leídos están separados por **tecla Tabulador (/t)** para formar una cadena, que se agrega a PlainTextEdit para su visualización.

La función item () de QStandardItemModel devuelve el elemento de datos en el área de trabajo de acuerdo con el número de fila y el número de columna, y su prototipo de función es:

item(self, rowNo, colNo: int = 0) -> QStandardItem

rowNo es el número de fila, colNo es el número de columna y el valor de retorno es un objeto QStandardItem.

El botón "Guardar archivo" en la barra de herramientas puede guardar los datos del modelo de datos como un archivo de texto, y el código de implementación es el siguiente:

   @pyqtSlot()  ##保存文件
   def on_actSave_triggered(self): 
##      curPath=QDir.currentPath() #获取当前路径
      curPath=os.getcwd()   #获取当前路径     
      filename,flt=QFileDialog.getSaveFileName(self,"保存文件",curPath,
                  "井斜数据文件(*.txt);;所有文件(*.*)")
      if (filename==""):
         return

      self.on_actModelData_triggered()  #更新数据到plainTextEdit

      aFile=open(filename,'w')  #以写方式打开
      aFile.write(self.ui.plainTextEdit.toPlainText())
      aFile.close()

Aquí, primero se llama a la función de ranura on_actModelData_triggered() para mostrar el contenido del modelo de datos en el componente PlainTextEdit, y luego **toPlainText()** de QPlainTextEdit se usa para exportar todo su contenido como texto y escribirlo en un archivo.

Supongo que te gusta

Origin blog.csdn.net/qq_35412059/article/details/126497192
Recomendado
Clasificación