2010-07-29 17 views
14

हम क्यूटी 4.6.3 के साथ एक QTableView का उपयोग कर रहे हैं, और एक स्तंभ केवल प्रत्येक कोशिका में एक चेकबॉक्स है कि जरूरत के लिए। हम QTableView के लिए मॉडल के रूप में QAbstractTableModel के एक कस्टम उपवर्ग का उपयोग कर रहे हैं। अभी, हमारे पास Qt::ItemIsUserCheckable ध्वज सेट करके एक चेकबॉक्स है। लेकिन हम यह नहीं समझ सकते कि चेकबॉक्स के बगल में खाली टेक्स्टबॉक्स से कैसे छुटकारा पाएं!क्यूटी QTableView कैसे एक चेकबॉक्स केवल स्तंभ

हम कॉलम केवल को चेकबॉक्स कैसे बना सकते हैं, और कुछ नहीं?

उत्तर

15

यहाँ एक समाधान है। इस ठीक से काम करने के लिए, अपने स्तंभ Qt::ItemIsEditable या Qt::ItemIsUserCheckable झंडे सेट नहींहोना चाहिए। यह Qt::DisplayRole से बूलियन मूल्यों पढ़ता है और Qt::EditRole साथ setData() कॉल

#include "check_box_delegate.h" 

#include <QtGui/QApplication> 
#include <QtGui/QMouseEvent> 

static QRect CheckBoxRect(const QStyleOptionViewItem &view_item_style_options) { 
    QStyleOptionButton check_box_style_option; 
    QRect check_box_rect = QApplication::style()->subElementRect(
     QStyle::SE_CheckBoxIndicator, 
     &check_box_style_option); 
    QPoint check_box_point(view_item_style_options.rect.x() + 
         view_item_style_options.rect.width()/2 - 
         check_box_rect.width()/2, 
         view_item_style_options.rect.y() + 
         view_item_style_options.rect.height()/2 - 
         check_box_rect.height()/2); 
    return QRect(check_box_point, check_box_rect.size()); 
} 

CheckBoxDelegate::CheckBoxDelegate(QObject *parent) 
    : QStyledItemDelegate(parent) { 
} 

void CheckBoxDelegate::paint(QPainter *painter, 
          const QStyleOptionViewItem &option, 
          const QModelIndex &index) const { 
    bool checked = index.model()->data(index, Qt::DisplayRole).toBool(); 

    QStyleOptionButton check_box_style_option; 
    check_box_style_option.state |= QStyle::State_Enabled; 
    if (checked) { 
    check_box_style_option.state |= QStyle::State_On; 
    } else { 
    check_box_style_option.state |= QStyle::State_Off; 
    } 
    check_box_style_option.rect = CheckBoxRect(option); 

    QApplication::style()->drawControl(QStyle::CE_CheckBox, 
            &check_box_style_option, 
            painter); 
} 

// This is essentially copied from QStyledItemEditor, except that we 
// have to determine our own "hot zone" for the mouse click. 
bool CheckBoxDelegate::editorEvent(QEvent *event, 
            QAbstractItemModel *model, 
            const QStyleOptionViewItem &option, 
            const QModelIndex &index) { 
    if ((event->type() == QEvent::MouseButtonRelease) || 
     (event->type() == QEvent::MouseButtonDblClick)) { 
    QMouseEvent *mouse_event = static_cast<QMouseEvent*>(event); 
    if (mouse_event->button() != Qt::LeftButton || 
     !CheckBoxRect(option).contains(mouse_event->pos())) { 
     return false; 
    } 
    if (event->type() == QEvent::MouseButtonDblClick) { 
     return true; 
    } 
    } else if (event->type() == QEvent::KeyPress) { 
    if (static_cast<QKeyEvent*>(event)->key() != Qt::Key_Space && 
     static_cast<QKeyEvent*>(event)->key() != Qt::Key_Select) { 
     return false; 
    } 
    } else { 
    return false; 
    } 

    bool checked = index.model()->data(index, Qt::DisplayRole).toBool(); 
    return model->setData(index, !checked, Qt::EditRole); 
} 
1

वे qtcentre में एक ही मुद्दा था। वहां वे प्रतिनिधियों के साथ एक समाधान में आए, शायद आपको उन पर एक नज़र डालना चाहिए।

+0

अधिक एक जवाब की तुलना में एक टिप्पणी की तरह लगता है? – neuronet

8

नोट (अर्थात नहींQt::CheckStateRole।): डेव के जवाब अजगर PySide या PyQt4 उपयोग करने के लिए भी काम करता है। मैंने इसका अनुवाद किया, और यह बहुत अच्छा काम करता है। साथ ही, मैं कार्यक्षमता चेकबॉक्स उपयोगकर्ता इनपुट को स्वीकार नहीं करता है और एक ReadOnly राज्य में दिखाया गया है, तो सेल संपादन योग्य नहीं है गयी। धन्यवाद आपके कोड के लिए डेव!

class CheckBoxDelegate(QStyledItemDelegate): 

    def createEditor(self, parent, option, index): 
     ''' 
     Important, otherwise an editor is created if the user clicks in this cell. 
     ''' 
     return None 

    def paint(self, painter, option, index): 
     ''' 
     Paint a checkbox without the label. 
     ''' 
     checked = bool(index.model().data(index, Qt.DisplayRole)) 
     check_box_style_option = QStyleOptionButton() 

     if (index.flags() & Qt.ItemIsEditable) > 0: 
      check_box_style_option.state |= QStyle.State_Enabled 
     else: 
      check_box_style_option.state |= QStyle.State_ReadOnly 

     if checked: 
      check_box_style_option.state |= QStyle.State_On 
     else: 
      check_box_style_option.state |= QStyle.State_Off 

     check_box_style_option.rect = self.getCheckBoxRect(option) 
      if not index.model().hasFlag(index, Qt.ItemIsEditable): 
      check_box_style_option.state |= QStyle.State_ReadOnly 

     QApplication.style().drawControl(QStyle.CE_CheckBox, check_box_style_option, painter) 


    def editorEvent(self, event, model, option, index): 
     ''' 
     Change the data in the model and the state of the checkbox 
     if the user presses the left mousebutton or presses 
     Key_Space or Key_Select and this cell is editable. Otherwise do nothing. 
     ''' 
     if not (index.flags() & Qt.ItemIsEditable) > 0: 
      return False 

     # Do not change the checkbox-state 
     if event.type() == QEvent.MouseButtonRelease or event.type() == QEvent.MouseButtonDblClick: 
      if event.button() != Qt.LeftButton or not self.getCheckBoxRect(option).contains(event.pos()): 
       return False 
      if event.type() == QEvent.MouseButtonDblClick: 
       return True 
     elif event.type() == QEvent.KeyPress: 
      if event.key() != Qt.Key_Space and event.key() != Qt.Key_Select: 
       return False 
     else: 
      return False 

     # Change the checkbox-state 
     self.setModelData(None, model, index) 
     return True 

    def setModelData (self, editor, model, index): 
     ''' 
     The user wanted to change the old state in the opposite. 
     ''' 
     newValue = not bool(index.model().data(index, Qt.DisplayRole)) 
     model.setData(index, newValue, Qt.EditRole) 


    def getCheckBoxRect(self, option): 
     check_box_style_option = QStyleOptionButton() 
     check_box_rect = QApplication.style().subElementRect(QStyle.SE_CheckBoxIndicator, check_box_style_option, None) 
     check_box_point = QPoint (option.rect.x() + 
          option.rect.width()/2 - 
          check_box_rect.width()/2, 
          option.rect.y() + 
          option.rect.height()/2 - 
          check_box_rect.height()/2) 
     return QRect(check_box_point, check_box_rect.size()) 
+0

रारो और @ निकलास, इस लिप्यंतरण के लिए धन्यवाद, लेकिन मुझे काम करने के लिए कोड नहीं मिल रहा है। मैंने अपने कार्यान्वयन के उदाहरण के साथ एक फॉलो अप [यहां।] (Http://stackoverflow.com/questions/17748546/pyqt-column-of-checkboxes-in-a-qtableview) पोस्ट किया है। – drexiya

+0

@ डेव मैटर वास्तव में प्रभावशाली .... मैं थोड़ा उलझन में हूं (अगर index (fl.fags() और Qt.ItemIsEditable)> 0: '। सूचकांक पर झंडे के अस्तित्व की जांच क्यों? – neuronet

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