2011-03-29 11 views
7

के साथ चित्रित प्रत्येक पंक्ति कस्टम पर क्लिक करने योग्य 'बटन' मैं QListView की प्रत्येक पंक्ति पर 'क्लिक करने योग्य' आइकन (या बटन) खींचना चाहता हूं, मैं अपने स्वयं के कस्टम "QAbstractItemDelegate" व्युत्पन्न कक्षा का उपयोग कर पेंट करने के लिए उपयोग कर रहा हूं । वे बटन पंक्ति की कस्टम स्थिति के साथ बदल सकते हैं (मेरे पास पेंटिंग के दौरान अंतर्निहित डेटा संरचना तक पहुंच है)।क्यूटी: QAbstractItemDelegate

इस तक पहुंचने का सबसे अच्छा तरीका क्या है?

उत्तर

6

अस्वीकरण: यह सबसे अच्छा तरीका नहीं हो सकता है, लेकिन यहां एक तरह से आप पूरा नियंत्रण है जहां है। हमें चेक बॉक्स ड्राइंग के साथ ऐसा करने के लिए जरूरी पाया गया।

QStyledItemDelegate से आप के वारिस कर सकते हैं (या QAbstractItemDelegate काम कर सकते हैं .. यह प्रयास नहीं किया है) और reimplement paint और editorEvent तरीकों। paint में नियंत्रण खींचने के लिए आप QStyle::drawControl() (उपयुक्त शैली विकल्पों को सेट करने के बाद) का उपयोग करते हैं, और उसके बाद मैन्युअल रूप से editorEvent में माउस हिट के लिए परीक्षण करें और इसके साथ कुछ करें। यदि स्मृति मुझे सही ढंग से कार्य करता है, इस कोड को काफी हद तक QStyledItemDelegate के लिए क्यूटी स्रोत कोड देख से प्रेरित था (खांसी, कॉपी, खांसी, खांसी)।

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

    if (option.state & QStyle::State_Selected) { 
    painter->setPen(QPen(Qt::NoPen)); 
    if (option.state & QStyle::State_Active) { 
     painter->setBrush(QBrush(QPalette().highlight())); 
    } 
    else { 
     painter->setBrush(QBrush(QPalette().color(QPalette::Inactive, 
               QPalette::Highlight))); 
    } 
    painter->drawRect(option.rect); 
    } 

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); 
} 

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 true; 
    } 
    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 = model->data(index, Qt::DisplayRole).toBool(); 
    return model->setData(index, !checked, Qt::EditRole); 
} 
+0

धन्यवाद। यह कोशिश करेगा। – JasonGenX

+1

एक प्रश्न, मैं किसी दिए गए पंक्ति के क्षेत्र में "एंटर" और "छोड़ें" माउस चाल का पता कैसे लगा सकता हूं? (यदि मैं माउस कर्सर के नीचे वर्तमान पंक्ति की एक हाइलाइटिंग को कार्यान्वित करना चाहता था) – JasonGenX

+0

मुझे लगता है कि यह 'QEvent :: MouseMove' है, लेकिन मुझे पूरी तरह से यकीन नहीं है। संभवतः सबसे आसान काम यह है कि वहां 'qDebug() << event-> टाइप() 'कथन डालें, आपको ऐप ड्राइव करें, और फिर जो भी आपको संभालने के लिए आवश्यक घटनाओं को ढूंढने के लिए थूक जाए, उसके माध्यम से थके हुए हों। –