2016-08-14 27 views
0

我有以下問題reagrding Qt的(使用的PyQt 5):讀數據與BackgroundRole

我已修改的,我發現對於QDataWidgetMapper和QAbstractTableModel和加入另外的if-子句的例子之一Qt.BackgroundRole作用於數據方法。

的目標是讓這取決於我的模型的內容不同的背景顏色(如紅色背景,如果數組元素等於「錯誤」)

,對於qlistview2效果很好,但不工作qLineEdits,它們映射到模型。我知道這不是默認的QDataWidgetMapper(只將模型的一部分映射到一個控件的一個屬性)。

將附加屬性/信息映射到行編輯(修改其背景顏色,可視性,行編輯啓用/未啓用)的最佳做法是什麼?

我需要爲模型內部的這些屬性(對於更復雜的模型)進行計算,並且不希望子類化QLineEdit(以實現基於QLineEdit文本內容更改顏色的特定方法)。

#!/usr/bin/env python 
# -*- coding: utf-8 -*- 

from PyQt5.QtWidgets import (QWidget, QDataWidgetMapper, 
           QLineEdit, QApplication, QGridLayout, QListView) 
from PyQt5.QtCore import Qt, QAbstractTableModel, QModelIndex 
from PyQt5.QtGui import QBrush 


class Window(QWidget): 
    def __init__(self, parent=None): 
     super(Window, self).__init__(parent) 

     # Set up the widgets. 
     self.nameEdit = QLineEdit() 
     self.nameEdit2 = QLineEdit() 

     # set up the layout 
     layout = QGridLayout() 
     layout.addWidget(self.nameEdit, 0, 1, 1, 1) 
     layout.addWidget(self.nameEdit2, 0, 2, 1, 1) 
     self.setLayout(layout) 

     self.mapper = None 

    def setModel(self, model): 
     # Set up the mapper. 
     self.mapper = QDataWidgetMapper(self) 
     self.mapper.setModel(model) 
     self.mapper.addMapping(self.nameEdit, 0) 
     self.mapper.addMapping(self.nameEdit2, 1) 
     self.mapper.toFirst() 


class MyModel(QAbstractTableModel): 
    def __init__(self, data, parent=None): 
     QAbstractTableModel.__init__(self, parent) 
     self.lst = data 

    def columnCount(self, parent=QModelIndex()): 
     return len(self.lst[0]) 

    def rowCount(self, parent=QModelIndex()): 
     return len(self.lst) 

    def data(self, index, role=Qt.DisplayRole): 
     row = index.row() 
     col = index.column() 

     if role == Qt.EditRole: 
      return self.lst[row][col] 
     elif role == Qt.DisplayRole: 
      return self.lst[row][col] 
     elif role == Qt.BackgroundRole: 
      redBackground = QBrush(Qt.red) 
      greenBackground = QBrush(Qt.green) 
      if self.lst[row][col] == "error": 
       return redBackground 
      else: 
       return greenBackground 

    def flags(self, index): 
     flags = super(MyModel, self).flags(index) 

     if index.isValid(): 
      flags |= Qt.ItemIsEditable 
      flags |= Qt.ItemIsDragEnabled 
     else: 
      flags = Qt.ItemIsDropEnabled 

     return flags 

    def setData(self, index, value, role=Qt.EditRole): 

     if not index.isValid() or role != Qt.EditRole: 
      return False 

     self.lst[index.row()][index.column()] = value 
     self.dataChanged.emit(index, index) 
     return True 


if __name__ == '__main__': 
    import sys 

    app = QApplication(sys.argv) 

    myModel = MyModel([['row 1 col1', 'error'], 
         ['error', 'row 2 col2'], 
         ['row 3 col1', 'row 3 col2'], 
         ['error', 'row 4 col2']]) 

    # myModel = MyModel() 
    mywindow = Window() 
    mywindow.setModel(myModel) 

    qlistview2 = QListView() 
    qlistview2.setModel(myModel) 

    mywindow.show() 
    qlistview2.show() 

    sys.exit(app.exec_()) 

回答

0

我已經找到了簡單的解決方案:我必須使用自定義代表來解決問題。

class LineDelegate(QStyledItemDelegate): 

    def __init__(self, parent = None): 
     QStyledItemDelegate.__init__(self, parent) 

    def createEditor(self, parent, option, index): 
     pass 

    def setEditorData(self, editor, index): 
     editor.setText(index.model().data(index, Qt.EditRole)) 
     color = index.model().data(index, Qt.BackgroundColorRole) 
     palette = QPalette() 
     palette.setBrush(QPalette.Base,color) 
     editor.setPalette(palette) 
     editor.repaint()   

    def setModelData(self, editor, model, index): 
     model.setData(index, editor.text(), Qt.EditRole) 

正如我需要多個委託來處理這兩個QLineEdits,the question and answer given by AlexVhr幫了不少忙。

完整的修改後的源代碼位於pastebin