Model/View 구조를 위한 커스텀 프록시

1. 사용자 정의 프록시 기능
편집을 위해 데이터 파일을 가져올 때 QTableView 구성 요소는 QLineEdit 구성 요소 인 각 셀에 대한 기본 프록시 편집 구성 요소를 제공합니다 . 편집 상자에는 모든 데이터를 입력할 수 있으므로 보다 일반적입니다. 하지만 어떤 경우에는 데이터 유형에 따라 다른 편집 구성 요소를 사용하고 싶습니다.

일부 데이터 유형은 정수, 부동 소수점 또는 드롭다운 상자이며 , 구성 요소를 QSpinBox, QDoubleSpinBox, QComboBox 로 편집해야 합니다 . 이러한 기능을 구현하려면 TableView 구성 요소의 특정 열이나 특정 셀에 대한 사용자 정의 프록시 구성 요소를 설정해야 합니다.
위의 두 가지 사용자 정의 프록시 클래스는 다음과 같습니다.
여기에 이미지 설명 삽입
여기에 이미지 설명 삽입

1. QDoubleSpinBox를 기반으로 한 QmyFloatSpinDelegate 클래스는 디지털 입력에 사용되며 소수 자릿수와 입력 데이터 범위를 설정할 수 있습니다.
2. QComboBox를 기반으로 하는 QmyComboBoxDelegate는 "시멘트 품질"의 데이터 입력에 사용되며 목록 선택 내용을 설정할 수 있습니다.

2. 사용자 정의 프록시 클래스의 기본 설계에는
PyQt5의 프록시와 관련된 여러 클래스의 계층 구조가 필요합니다.
여기에 이미지 설명 삽입
QAbstractItemDelegate 는 모든 프록시 클래스의 추상 기본 클래스이고, QStyledItemDelegate 는 뷰 구성 요소에서 사용하는 기본 프록시 클래스이며, QItemDelegate 도 클래스입니다. 유사한 기능을 가진. QStyledItemDelegate와 QItemDelegate의 차이점은 다음과 같습니다. QStyledItemDelegate는 현재 스타일 시트 설정을 사용하여 구성 요소를 그릴 수 있으므로 QStyledItemDelegate를 사용자 정의 프록시 구성 요소의 기본 클래스로 사용하는 것이 좋습니다.

사용자 정의 프록시 클래스의 4가지 함수:
createEditor() 함수 : QSpinBox 구성 요소 또는 QComboBox 구성 요소와 같은 모델 데이터를 편집하기 위한 위젯 구성 요소를 생성합니다.
setEditData() 함수 :
setModelData() 를 편집할 위젯 구성 요소에 대한 데이터 모델에서 데이터를 얻습니다. 기능 : 위젯의 데이터를 데이터 모델
updateEditorGeometry()로 업데이트합니다. 기능 : 위젯 그래프 구성 요소에 적절한 크기를 설정하는 데 사용됩니다.

3. QDoubleSpinBox 기반 사용자 정의 프록시 클래스

from PyQt5.QtWidgets import  QStyledItemDelegate,QDoubleSpinBox,QComboBox

from PyQt5.QtCore import  Qt

## ==============基于QDoubleSpinbox的代理组件====================
class QmyFloatSpinDelegate(QStyledItemDelegate):
   def __init__(self, minV=0,maxV=10000,digi=2,parent=None):    #构造函数传入3个参数
      super().__init__(parent)
	
	#定义3个私有变量存储3个参数
      self.__min=minV
      self.__max=maxV
      self.__decimals=digi

## 自定义代理组件必须继承以下4个函数
   def createEditor(self, parent, option, index):
      editor = QDoubleSpinBox(parent)    #创建使用的编辑器组件
      editor.setFrame(False)
      editor.setRange(self.__min,self.__max)
      editor.setDecimals(self.__decimals)
      return editor

   def setEditorData(self,editor,index):
      model=index.model()     #关联的数据模型
      text=model.data(index, Qt.EditRole)  #单元格文字
##      value = float(index.model().data(index, Qt.EditRole))
      editor.setValue(float(text))
        
   def setModelData(self,editor,model,index):
      value = editor.value()
      model.setData(index, value, Qt.EditRole)
##        digi="{:.%df}"%self.__decimals  # 获得 "{:.2f}", 会改变小数位数
##        text=digi.format(value)     #相当于 "{:.2f}.format(value)"
##        model.setData(index, text, Qt.EditRole)
    
   def updateEditorGeometry(self,editor,option,index):
      editor.setGeometry(option.rect)

위 코드를 분석하십시오.
QmyFloatSpinDelegate의 상위 클래스는 QStyledItemDelegate이고 사용된 편집기 구성 요소는 QDoubleSpinBox입니다.
QmyFloatSpinDelegate의 생성자는 각각 최소값, 최대값 및 소수 자릿수를 설정하는 데 사용되는 minV, maxV 및 digi 매개변수를 전달할 수 있으며 이 세 매개변수에는 기본값이 있습니다. 클래스에는 세 가지 매개 변수를 각각 저장하는 데 사용되는 세 가지 개인 변수가 정의되어 있습니다.
그런 다음 프록시 구성 요소의 네 가지 기본 기능을 구현합니다.
(1) CreateEditor(부모, 옵션, 인덱스): 필요한 편집기 구성 요소를 생성 하고 함수의 반환 값 역할을 하는 데 사용됩니다. 함수의 매개변수 parent는 프록시 구성요소의 상위 컨테이너 개체입니다. option은 생성된 편집기 구성요소의 효과에 대한 일부 고급 설정을 만들 수 있는 QStyleOptionViewItem 유형 변수입니다. index는 모델 인덱스인 QModelIndex 변수입니다. 관련 데이터 항목은 index.model()을 통해 관련 데이터 모델을 얻을 수 있습니다.

TableView 컴포넌트의 셀을 더블클릭하여 편집 상태로 들어가면 이 함수가 호출되어 QDoubleSpinBox 컴포넌트를 생성하고 셀에 표시합니다.

(2) setEditorData(editor, index): 데이터 모델에서 데이터를 가져와서 에디터의 표시값으로 설정하는데 사용됩니다 . 함수에 의해 전달된 매개변수 편집기는 프록시 편집기 구성요소, 즉 createEditor() 함수에서 생성된 QDoubleSpinBox 개체를 가리킵니다. index는 연관된 데이터 단위의 모델 인덱스이고, index.model()은 연관된 데이터 모델을 가리킨 다음 모델의 data(index, Qt.EditRole) 함수를 통해 셀의 표시 텍스트 텍스트를 얻은 다음 텍스트를 프록시 구성 요소의 표시 값에 할당된 부동 소수점 숫자로 변환합니다.

(3) **setModelData(editor, model, index): 프록시 편집기의 값을 데이터 모델로 업데이트하는 데 사용됩니다. 이 함수는 사용자가 인터페이스에서 편집을 마치면 자동으로 호출됩니다. **파라미터 에디터는 생성된 에디터 컴포넌트이고, 모델은 연관 데이터 모델, 인덱스는 연관 셀의 모델 인덱스입니다. 프로그램에서 먼저 프록시 컴포넌트 편집기의 숫자 값을 얻은 다음 이 값을 데이터 모델로 업데이트합니다.

(4) updateEditorGeometry(editor, option, index): 프록시 컴포넌트 에디터의 표시 효과를 설정하는 데 사용됩니다 . 매개변수 옵션은 QStyleOptionViewItem 유형 변수이며 ret 속성은 프록시를 표시하는 데 적합한 셀의 크기를 정의합니다. 이 값으로 프로그램에서 직접 설정됩니다. index는 연관된 데이터 항목의 모델 인덱스입니다.

4. QComboBox 기반의 맞춤형 프록시 클래스

## ==============基于QComboBox的代理组件====================
class QmyComboBoxDelegate(QStyledItemDelegate):
   def __init__(self, parent=None):
      super().__init__(parent)
      self.__itemList=[]
      self.__isEditable=False
        

   def setItems(self,itemList, isEditable=False):
      self.__itemList=itemList
      self.__isEditable=isEditable

## 自定义代理组件必须继承以下4个函数
   def createEditor(self, parent, option, index):
      editor = QComboBox(parent)
      editor.setFrame(False)
      editor.setEditable(self.__isEditable)
      editor.addItems(self.__itemList)
      return editor

   def setEditorData(self,editor,index):
      model=index.model()
      text = model.data(index, Qt.EditRole)
##      text = str(index.model().data(index, Qt.EditRole))
      editor.setCurrentText(text)
        
   def setModelData(self,editor,model,index):
      text = editor.currentText()
      model.setData(index, text, Qt.EditRole)
    
   def updateEditorGeometry(self,editor,option,index):
      editor.setGeometry(option.rect)

QmyComboBoxDelegate의 생성자는 개인 변수 self.__itemList를 정의하여 QComboBox 구성 요소의 드롭다운 목록 내용을 저장하고 개인 변수 self.__isEditable을 정의하여 QComboBox 구성 요소를 편집할 수 있는지 여부를 설정합니다.

사용자 정의 인터페이스 함수인 setItems()는 이 두 개인 변수에 값을 할당하는 데 사용됩니다. createEditor() 함수에서 QComboBox 구성 요소 편집기를 만든 후 이 두 변수를 사용하여 편집기의 드롭다운 목록 내용과 편집 가능한 속성 값을 설정합니다.

다섯째, 사용자 지정 프록시 클래스 사용

#导入myDelegates.py文件中定义的两个代理类
from myDelegates import QmyFloatSpinDelegate, QmyComboBoxDelegate

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.__buildStatusBar()

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

##      headerList=["测深(m)","垂深(m)","方位(°)","总位移(m)","固井质量","测井取样"]
##      self.itemModel.setHorizontalHeaderLabels(headerList) #设置表头文字

      self.selectionModel = QItemSelectionModel(self.itemModel) #Item选择模型
      self.selectionModel.currentChanged.connect(self.do_currentChanged)
      self.__lastColumnFlags=(Qt.ItemIsSelectable | Qt.ItemIsUserCheckable | Qt.ItemIsEnabled)
      self.__lastColumnTitle="测井取样"
      
      #为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.setEnabled(False)  #先禁用tableView
##      self.__resetTable(5)

      #创建自定义代理组件并设置
      self.spinCeShen=QmyFloatSpinDelegate(0,10000, 0,self)    #用于 测深
      self.spinLength=QmyFloatSpinDelegate(0,6000,  2,self)    #垂深,总位移
      self.spinDegree=QmyFloatSpinDelegate(0,360,   1,self)    #用于 方位

      self.ui.tableView.setItemDelegateForColumn(0,self.spinCeShen)  #测深
      self.ui.tableView.setItemDelegateForColumn(1,self.spinLength)  #垂深
      self.ui.tableView.setItemDelegateForColumn(3,self.spinLength)  #总位移
      self.ui.tableView.setItemDelegateForColumn(2,self.spinDegree)  #方位角

      qualities=["优","良","合格","不合格"]
      self.comboDelegate=QmyComboBoxDelegate(self)
      self.comboDelegate.setItems(qualities,False) #不可编辑
      self.ui.tableView.setItemDelegateForColumn(4,self.comboDelegate)  #固井质量

QmyMainWindow 클래스의 생성자에 프록시 구성 요소를 설정하는 코드를 추가합니다.

QmyFloatSpinDelegate 유형의 세 가지 프록시 구성요소가 생성되지만 서로 다른 데이터 열에 대해 서로 다른 데이터 범위와 소수 자릿수가 설정됩니다.

QmyComboBoxDelegate 유형의 프록시 구성 요소를 만들고 setItems() 함수를 호출하여 드롭다운 목록과 편집 가능한 속성을 초기화합니다.

QTableView 구성요소의 행, 열 또는 전체 테이블에 대해 프록시 구성요소를 설정할 수 있습니다.QTableView에서 사용되는 기능은 다음과 같습니다.

(1) setItemDelegateForColumn(column, Delegate), 특정 열에 대한 프록시 구성 요소 위임을 설정합니다 . 이 예에서 열은 필드이므로 setItemDelegateForColumn() 함수를 사용하여 열에 대한 위임 구성 요소를 설정합니다.
(2) setItemDelegateForRow(row, Delegate), 특정 행에 대한 프록시 구성 요소 위임을 설정합니다 .
(3) setItemDelegate(delegate), 전체 TableView 구성 요소에 대한 프록시 구성 요소 위임을 설정합니다 .

Supongo que te gusta

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