2015-01-22 2 views
1

QTableViewQAbstractTableModel으로 제어됩니다. 그 내용을 채우는 모델입니다. 그리고 사용자가 QTableView의 항목 중 하나를 두 번 클릭 한 다음 새 값을 입력 한 결과로 self.items 변수를 수정하는 모델입니다.QAbstractTableModel 모델을 사용하여 다른 위젯을 제어하는 ​​방법은 무엇입니까?

대화 상자의 아래쪽에있는 단추는 처음에는 사용할 수 없습니다. 사용자가 새 값을 입력하자마자 (이 버튼을 QTableView의 항목 중 하나를 두 번 클릭하고 문자열이나 숫자를 입력하여)이 버튼을 활성화하고 싶습니다.

본질적으로 모델이 버튼의 상태를 제어하기를 원합니다. 그것을 어떻게 성취 할 수 있습니까?

enter image description here

from PyQt4.QtCore import * 
from PyQt4.QtGui import * 
import sys, os 

class Model(QAbstractTableModel): 
    def __init__(self, parent=None, *args): 
     QAbstractTableModel.__init__(self, parent, *args) 
     self.items =[ 
        ['Row0_Column0','Row0_Column1','Row0_Column2'], 
        ['Row1_Column0','Row1_Column1','Row1_Column2'], 
        ['Row2_Column0','Row2_Column1','Row2_Column2'] 
        ] 

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

    def rowCount(self, parent): 
     return len(self.items)  
    def columnCount(self, parent): 
     return 3 

    def data(self, index, role): 
     if not index.isValid(): return QVariant() 
     row=index.row() 
     column=index.column() 

     if row>len(self.items): return QVariant()   
     if column>len(self.items[row]): return QVariant() 

     if role == Qt.EditRole: 
      return QVariant(self.items[row][column]) 

     if role == Qt.DisplayRole:    
      return QVariant(self.items[row][column]) 

     return QVariant() 

    def setData(self, index, value, role=Qt.EditRole): 
     if index.isValid():    
      if role == Qt.EditRole: 
       row = index.row() 
       column=index.column() 
       if row>len(self.items) or column>len(self.items[row]): 
        return False 
       else: 
        self.items[row][column]=value 
        return True 
     return False 

class MyWindow(QWidget): 
    def __init__(self, *args): 
     QWidget.__init__(self, *args) 
     tablemodel=Model(self)    
     tableview=QTableView(self) 
     tableview.setModel(tablemodel)  
     layout=QVBoxLayout(self) 
     layout.addWidget(tableview) 
     self.button=QPushButton('Push Me') 
     self.button.setDisabled(True) 
     layout.addWidget(self.button) 
     self.setLayout(layout)  

if __name__ == "__main__": 
    app = QApplication(sys.argv) 
    w = MyWindow() 
    w.show() 
    sys.exit(app.exec_()) 
+1

저는 파이썬을 좋아하지 않지만 힌트를 줄 수 있습니다. 'void QAbstractItemModel :: dataChanged (...)'신호를 사용하여 사용자가 언제 셀을 더블 클릭하여 새로운 값을 입력했는지 알 수 있습니다. 이 신호를 새 셀 내용을 문자열 형식으로 가져 오는 슬롯에 연결하고이 새 문자열로 푸시 단추를 실현하십시오. – Martin

+0

감사! 나는 그것을 시도 할 것이다! – alphanumeric

답변

1

Martin에 의해 주석이 이미 좋은 출발점이지만, 사용자 정의 모델에서 당신은 또한 작동하기 위해서는 사항 setData 방법에 dataChanged 신호를 방출해야합니다.

다음 사용자 정의 신호를 정의하여 방출 할 수 있습니다.

from PySide import QtGui, QtCore 

class Model(QtCore.QAbstractTableModel): 
    def __init__(self, parent=None, *args): 
     QtCore.QAbstractTableModel.__init__(self, parent, *args) 
     self.items =[ 
        ['Row0_Column0','Row0_Column1','Row0_Column2'], 
        ['Row1_Column0','Row1_Column1','Row1_Column2'], 
        ['Row2_Column0','Row2_Column1','Row2_Column2'] 
        ] 

    def flags(self, index): 
     return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEditable 

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

    def columnCount(self, parent): 
     return 3 

    def data(self, index, role): 
     if not index.isValid(): 
      return None 

     row=index.row() 
     column=index.column() 

     if row > len(self.items): 
      return None 
     if column > len(self.items[row]): 
      return None 

     if role == QtCore.Qt.EditRole: 
      return self.items[row][column] 

     if role == QtCore.Qt.DisplayRole: 
      return self.items[row][column] 

     return None 

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

       row = index.row() 
       column = index.column() 

       if row > len(self.items) or column > len(self.items[row]): 
        return False 
       else: 
        self.items[row][column] = value 
        self.dataChanged.emit(index, index) # emit the signal 
        return True 
     return False 

class MyWindow(QtGui.QWidget): 
    def __init__(self, *args): 
     QtGui.QWidget.__init__(self, *args) 

     tablemodel = Model(self) 
     tablemodel.dataChanged.connect(self.data_changed) # connect dataChanged signal 
     tableview = QtGui.QTableView(self) 
     tableview.setModel(tablemodel) 

     layout = QtGui.QVBoxLayout(self) 
     layout.addWidget(tableview) 

     self.button = QtGui.QPushButton('Push Me') 
     self.button.setDisabled(True) # initially disabled 

     layout.addWidget(self.button) 
     self.setLayout(layout) 

    def data_changed(self, topleft_index, bottom_right_index): 
     # just enable the button 
     self.button.setEnabled(True) 

app = QtGui.QApplication([]) 
w = MyWindow() 
w.show() 
app.exec_() 

주석 처리 된 줄은 중요한 것들이다 : 그러나, 여기 QAbstractItemModel의 dataChanged 신호와 함께 예입니다.

관련 문제