2010-05-03 6 views
11

मैं QTreeView के किसी हिस्से में क्लिक करके अपने QTreeView में आइटम्स को अचयनित करने में सक्षम होना चाहता हूं, लेकिन मुझे ऐसा करने के लिए कोई प्रतीत नहीं होता है। मैं एक क्लिक पर रोक लगाता हूं जो किसी आइटम पर नहीं है, लेकिन QTreeView में clicked सिग्नल नहीं है, इसलिए मैं यह नहीं कर सकता कि यह कैसे करें।क्या किसी आइटम को क्लिक करके QTreeView में अचयनित करना संभव है?

उत्तर

10

यह वास्तव में (PyQt में) काफी सरल है:

class DeselectableTreeView(QtGui.QTreeView): 
    def mousePressEvent(self, event): 
     self.clearSelection() 
     QtGui.QTreeView.mousePressEvent(self, event) 

क्यूटी mousePressEvent का उपयोग करता clicked फेंकना। यदि आप ईवेंट भेजने से पहले चयन को साफ़ करते हैं, तो यदि कोई आइटम क्लिक किया गया है तो इसे चुना जाएगा, अन्यथा कुछ भी नहीं चुना जाएगा। Patrice को इस के साथ मेरी मदद करने के लिए बहुत धन्यवाद :)

7

QTreeViewQAbstractView (http://doc.qt.digia.com/4.6/qtreeview.html) से विरासत में clicked सिग्नल है। समस्या यह है कि सिग्नल उत्सर्जित होता है जब सूचकांक मान्य होता है ताकि आप इस सिग्नल के साथ जो चाहते हैं उसे प्राप्त नहीं कर सकें।

इसके बजाय mousePressEvent को अवरुद्ध करने का प्रयास करें। फ़ंक्शन में आप यह पता लगा सकते हैं कि उपयोगकर्ता ने जहां आवश्यक हो तो चयनित आइटम को क्लिक और अचयनित किया है।

+0

धन्यवाद। मैंने अपना जवाब जोड़ा है लेकिन +1 क्योंकि आपने मुझे वहां जाने में मदद की! – Skilldrick

+0

आपका स्वागत है स्किलड्रिक –

0

आप अपने विजेट के लिए एक अलग selection mode सेट करने का प्रयास कर सकते हैं। मुझे नहीं पता कि उनमें से कोई भी जो कुछ भी आप चाहते हैं उसे कवर करता है (एकल चयन, लेकिन अचयनित)।

+0

मैं वहां कुछ भी नहीं देख सका जो मैं चाहता था, लेकिन वैसे भी धन्यवाद। – Skilldrick

8

स्पष्ट चयन मेरे मामले में काम नहीं करता है। मैं सिंगलसेक्शन मोड के साथ वृक्षदृश्य का उपयोग कर रहा हूं। यहां मैंने जो कोड किया है:

class DeselectableTreeView : public QTreeView 
{ 
public: 
    DeselectableTreeView(QWidget *parent) : QTreeView(parent) {} 
    virtual ~DeselectableTreeView() {} 

private: 
    virtual void mousePressEvent(QMouseEvent *event) 
    { 
     QModelIndex item = indexAt(event->pos()); 
     bool selected = selectionModel()->isSelected(item); 
     QTreeView::mousePressEvent(event); 
     if (selected) 
      selectionModel()->select(item, QItemSelectionModel::Deselect); 
    } 

}; 

यह वास्तव में ठीक काम करता है।

एरिक

13

@ के आधार पर एरिक के समाधान, और यह केवल deselects मानो क्लिक किया आइटम का चयन किया गया था, यहाँ है कि मैं क्या के साथ आया था। यह समाधान भी जब आप QTreeView

#ifndef DESELECTABLETREEVIEW_H 
#define DESELECTABLETREEVIEW_H 
#include "QTreeView" 
#include "QMouseEvent" 
#include "QDebug" 
class DeselectableTreeView : public QTreeView 
{ 
public: 
    DeselectableTreeView(QWidget *parent) : QTreeView(parent) {} 
    virtual ~DeselectableTreeView() {} 

private: 
    virtual void mousePressEvent(QMouseEvent *event) 
    { 
     QModelIndex item = indexAt(event->pos()); 
     bool selected = selectionModel()->isSelected(indexAt(event->pos())); 
     QTreeView::mousePressEvent(event); 
     if ((item.row() == -1 && item.column() == -1) || selected) 
     { 
      clearSelection(); 
      const QModelIndex index; 
      selectionModel()->setCurrentIndex(index, QItemSelectionModel::Select); 
     } 
    } 
}; 
#endif // DESELECTABLETREEVIEW_H 

यासिर

+2

+1 यह वही था जो मैं ढूंढ रहा था। – aardvarkk

+0

'indexAt' काफी महंगा हो सकता है, आप दूसरे कॉल के बजाय' item' का उपयोग कर सकते हैं। 'item.isValid()' पंक्ति और कॉलम की तुलना '-1' से तुलना करने की तुलना में शायद बेहतर विकल्प है। इसके अलावा, यह तत्वों पर क्लिक करते समय चयन को बदलता प्रतीत होता है? –

1

के खाली क्षेत्र पर क्लिक करें काम करता है @Skilldrick के जवाब देने के लिए जोड़ने के लिए, यदि आप एक राय यह है कि पहले से ही किया गया है करने के लिए इस आवेदन करने की आवश्यकता

import new 
def mousePressEvent(self, event): 
    self.clearSelection() 
    QtGui.QTableView.mousePressEvent(self, event) 
self.ui.tableView.mousePressEvent = new.instancemethod(mousePressEvent, self.ui.tableView, None) 

मतलब यह है कि आपके विचार self.ui.tableView है: instantiated क्योंकि आप क्यूटी डिजाइनर का उपयोग कर रहे हैं, तो आप कुछ इस तरह कर सकते हैं।

इस उत्तर के लिए धन्यवाद: https://stackoverflow.com/a/1647616/1300519

0

@Skilldrick द्वारा जवाब में, हम ज़रूरत से ज़्यादा ईवेंट भेजने से जोखिम। यदि कोई आइटम पहले से ही चुना गया है, और हम इसे फिर से क्लिक कर रहे हैं, तो हम अचयनित और चयनित घटनाओं को उठा रहे हैं। आपके आवेदन में अन्य श्रोताओं के आधार पर, यह संभव नहीं हो सकता है कि आप क्या चाहते हैं।

@ एरिक-माकर द्वारा समाधान केवल एक आइटम को अचयनित करता है अगर हम इसे पहले से चुनते समय फिर से क्लिक करते हैं। कड़ाई से बोलते हुए, यह मूल प्रश्न का उत्तर नहीं है, जो पर कहीं और पर क्लिक करते समय चयनित आइटम को अचयनित करने का तरीका था।

@ यासीर-एननाज़क निकट हो जाता है, लेकिन जैसा कि @ एड्रियन-मायर द्वारा इंगित किया गया है, समाधान अनुकूल नहीं है। event->pos() का मूल्यांकन दो बार किया जाता है। साथ ही, QTreeView::mousePressEvent पर कॉल करके माउस इवेंट का हमेशा मूल्यांकन किया जाता है।

ऊपर उल्लिखित अन्य उत्तरों के आधार पर, मैं जिस समाधान के साथ आया हूं, उसका समाधान यहां आया है। यदि हम उस बिंदु पर क्लिक कर रहे हैं जहां एक और पेड़ दृश्य आइटम मौजूद है, तो नया आइटम TreeView पर अग्रेषित करके नया आइटम चुना जाता है। यदि नहीं, तो हम चयन को साफ़ कर रहे हैं।

ध्यान दें कि यह QTreeWidget एस के लिए भी काम करता है।

virtual void mousePressEvent(QMouseEvent* event) 
{ 
    QModelIndex item = indexAt(event->pos()); 

    if (item.isValid()) 
    { 
     QTreeView::mousePressEvent(event); 
    } 
    else 
    { 
     clearSelection(); 
     const QModelIndex index; 
     selectionModel()->setCurrentIndex(index, QItemSelectionModel::Select); 
    } 
} 
+0

डिफ़ॉल्ट कार्यान्वयन के साथ गलत बात यह है कि दृश्य के रिक्त क्षेत्र पर क्लिक करते समय यह चयन को साफ़ नहीं करता है। तो बस जांचें कि सूचकांक के रूप में सूचकांक मान्य है या नहीं। यदि ऐसा नहीं है, तो 'स्पष्ट चयन() 'पर कॉल करें। फिर बिना शर्त रूप से बेस-क्लास 'माउसPressEvent' को कॉल करें। – ekhumoro

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