2013-07-12 8 views
5

का उपयोग कर तालिका दृश्य में QComboBox को कैसे सेट करें, मैं अपनी तालिका में एक कॉम्बो बॉक्स प्रदर्शित करने की कोशिश कर रहा हूं, ताकि मैं तालिका में अन्य कक्षों के साथ तालिका मॉडल से चयनित अनुक्रमणिका सेट कर सकूं। मैंने इसे अन्य उदाहरणों से एक साथ पा लिया है लेकिन अभी भी यह समझ में नहीं आता कि क्यूकंबोबॉक्स के चयनित इंडेक्स को सेट करने के लिए बातचीत कैसे काम करती है।पीईक्यूटी - QItemDelegate

यह सबसे सरल उदाहरण है जो मैं समस्या का प्रदर्शन करने के लिए आ सकता हूं। यदि कोई मॉडल मॉडल से स्वचालित रूप से इंडेक्स सेट करने का तरीका प्रदर्शित कर सकता है? इसके अलावा 'currentIndexChanged' सिग्नल का उपयोग कैसे करें, क्योंकि जब भी यह पुन: चित्रित होता है तो यह लगभग लगातार आग लग रहा है? धन्यवाद।

# The following tells SIP (the system that binds Qt's C++ to Python) 
# to return Python native types rather than QString and QVariant 
import sip 
sip.setapi('QString', 2) 
sip.setapi('QVariant', 2) 


from PyQt4 import QtCore, QtGui 

class TableModel(QtCore.QAbstractTableModel): 
    """ 
    A simple 5x4 table model to demonstrate the delegates 
    """ 
    def rowCount(self, parent=QtCore.QModelIndex()): return 5 
    def columnCount(self, parent=QtCore.QModelIndex()): return 4 

    def data(self, index, role=QtCore.Qt.DisplayRole): 
     if not index.isValid(): return None 
     if not role==QtCore.Qt.DisplayRole: return None 
     return "{0:02d}".format(index.row()) 


class ComboDelegate(QtGui.QItemDelegate): 
    """ 
    A delegate that places a fully functioning QComboBox in every 
    cell of the column to which it's applied 
    """ 
    def __init__(self, parent): 

     QtGui.QItemDelegate.__init__(self, parent) 

    def paint(self, painter, option, index): 

     self.combo = QtGui.QComboBox(self.parent()) 
     self.connect(self.combo, QtCore.SIGNAL("currentIndexChanged(int)"), self.parent().currentIndexChanged) 

     li = [] 
     li.append("Zero") 
     li.append("One") 
     li.append("Two") 
     li.append("Three") 
     li.append("Four") 
     li.append("Five") 

     self.combo.addItems(li) 

     if not self.parent().indexWidget(index): 
      self.parent().setIndexWidget(
       index, 
       self.combo 
      ) 

class TableView(QtGui.QTableView): 
    """ 
    A simple table to demonstrate the QComboBox delegate. 
    """ 
    def __init__(self, *args, **kwargs): 
     QtGui.QTableView.__init__(self, *args, **kwargs) 

     # Set the delegate for column 0 of our table 
     # self.setItemDelegateForColumn(0, ButtonDelegate(self)) 
     self.setItemDelegateForColumn(0, ComboDelegate(self)) 

    @QtCore.pyqtSlot() 
    def currentIndexChanged(self, ind): 
     print "Combo Index changed {0} {1} : {2}".format(ind, self.sender().currentIndex(), self.sender().currentText()) 

if __name__=="__main__": 
    from sys import argv, exit 

    class Widget(QtGui.QWidget): 
     """ 
     A simple test widget to contain and own the model and table. 
     """ 
     def __init__(self, parent=None): 
      QtGui.QWidget.__init__(self, parent) 

      l=QtGui.QVBoxLayout(self) 
      self._tm=TableModel(self) 
      self._tv=TableView(self) 
      self._tv.setModel(self._tm) 
      l.addWidget(self._tv) 

    a=QtGui.QApplication(argv) 
    w=Widget() 
    w.show() 
    w.raise_() 
    exit(a.exec_()) 

उत्तर

17

आप paint विधि गलत तरीके से उपयोग कर रहे हैं। इसका उपयोग तब किया जाना चाहिए जब आप दृश्य के प्रदर्शन व्यवहार को बदलना चाहते हैं। हर बार जब आप इसे पेंट करना चाहते हैं तो नया विजेट भी बनाना बहुत महंगा है। लेकिन आप संपादन व्यवहार को बदलना चाहते हैं ताकि आपको अपने कार्यक्रम के पूरे तर्क को बदलना पड़े।

fixed code देखें। नीचे मैं परिवर्तनों को समाप्त कर दूंगा।

1. सबसे पहले, हमें पहला कॉलम संपादन योग्य बनाने की आवश्यकता है। आप QAbstractItemModel::flags reimplementing द्वारा यह कर सकते हैं:

def flags(self, index): 
    if (index.column() == 0): 
     return QtCore.Qt.ItemIsEditable | QtCore.Qt.ItemIsEnabled 
    else: 
     return QtCore.Qt.ItemIsEnabled 

2. डिफ़ॉल्ट रूप से जब उपयोगकर्ता मद पर एक डबल क्लिक करता है आइटम संपादक बनाया गया है। आप डिफ़ॉल्ट रूप से सभी comboboxes दिखाना चाहते हैं, तो आप openPersistentEditor उपयोग कर सकते हैं:

for row in range(0, self._tm.rowCount()): 
    self._tv.openPersistentEditor(self._tm.index(row, 0)) 

ध्यान दें कि आपको चाहिए नव निर्मित कोशिकाओं के लिए भी खुला संपादकों (यदि हो तो)।

3. अब हमारे प्रतिनिधि को वापस।

def createEditor(self, parent, option, index): 
    combo = QtGui.QComboBox(parent) 
    li = [] 
    li.append("Zero") 
    li.append("One") 
    li.append("Two") 
    li.append("Three") 
    li.append("Four") 
    li.append("Five") 
    combo.addItems(li) 
    self.connect(combo, QtCore.SIGNAL("currentIndexChanged(int)"), 
       self, QtCore.SLOT("currentIndexChanged()")) 
    return combo 

ध्यान दें कि connectappend रों नीचे है, क्योंकि हम आरंभीकरण पर currentIndexChanged संकेतों से बचने की जरूरत: हम createEditor विधि कि स्वचालित रूप से देखने से बुलाया जाएगा एक संपादक एक सेल के लिए अनुरोध किया जाता है जब लागू करने के लिए की जरूरत है।

4.setEditorData विधि लागू करें जो मॉडल डेटा बदलते समय दृश्य द्वारा बुलाया जाएगा। एक संपादक को प्रारंभ होने पर भी इसे एक बार बुलाया जाएगा।

def setEditorData(self, editor, index): 
    editor.blockSignals(True) 
    editor.setCurrentIndex(int(index.model().data(index))) 
    editor.blockSignals(False) 

फिर, हम संकेत है कि उपयोगकर्ता की वजह से नहीं कर रहे हैं से बचना चाहते हैं, तो हम blockSignals का उपयोग करें।

5. स्लॉट में हम बस commitData संकेत है कि दृश्य हमारे प्रतिनिधि के setModelData कॉल करने के लिए कारण होगा फेंकना:

@QtCore.pyqtSlot() 
def currentIndexChanged(self): 
    self.commitData.emit(self.sender()) 

6.setModelData विधि को लागू करें:

def setModelData(self, editor, model, index): 
    model.setData(index, editor.currentIndex()) 

7. आपका मॉडल की जरूरत है डेटा बदलने का समर्थन करें।

def setData(self, index, value, role=QtCore.Qt.DisplayRole): 
    print "setData", index.row(), index.column(), value 
    # todo: remember the data 
+0

मैं डेटा मॉडल [यहां] (http://stackoverflow.com/questions/17697352/pyqt-implement-a-qabstracttablemodel बारे में एक प्रश्न का पालन जोड़ लिया है: तो हम मॉडल की setData विधि को लागू करना चाहिए -फॉर-इन-क्यूटेक्स्टव्यू) इस प्रश्न को विस्तारित करने के बजाए बहुत अधिक है। – drexiya

+0

दृश्य में चेकबॉक्स के कॉलम को जोड़ने के संबंध में एक और अनुवर्ती प्रश्न [यहां] (http://stackoverflow.com/questions/17748546/pyqt-column-of-checkboxes-in-a-qtableview)। – drexiya

संबंधित मुद्दे