2016-10-31 28 views
6

'a bağlı QListView'daki dosyaların renklerini değiştirmek için QListViewQFileSystemModel numaralı telefonu kullanıyorum. QTreeView'daki bir seçime bağlı olarak, QListView klasörün içeriğini gösterir.
Şimdi bazı koşullara bağlı olarak dosya isimlerinin rengini değiştirmem gerekiyor.
İlk fikir, QListView öğesindeki öğeler üzerinde yineleme yapmak ve koşulun yerine getirilip getirilmediğine bağlı olarak her öğe için rengi ayarlamak olacaktır. QFileSystemModel ait setData() yöntemi yalnızca böyle bir şey yok sayarak, EditRole değişiklik kabul Ancak bu, imkansız gibi görünüyorKoşullu olarak QFileSystemModel

self.FileModel.setData(index, QtGui.QBrush(QtCore.Qt.red), role=QtCore.Qt.ForegroundRole) 

Bu aynı zamanda here işaret edilmiştir ve birincide öneri oldu [this bakınız] QListView'daki öğeleri renklendirmek amacıyla QItemDelegate alt sınıfı.

Bu nedenle, QStyledItemDelegate alt sınıfına aldım ve koşulun yerine getirilmesi durumunda dosya adını yeşil renkte göstermek için paint() yöntemini yeniden oluşturdum. Ancak şimdi çirkin görünüyor: Dosya simgeleri kaybolur ve "mouse_over" etkisi artık çalışmıyor.

bu sınıflara zaten dağınık iş çevresinde iken

, benim üst düzey soru bir koşula dayalı bir QFileSystemModel bağlı bir QListView öğeleri renklendirmek için bir yolu var mı

  • olurdu?

Şimdi

  • geri güzel seçimler ve simgelerle orijinal davranışını almanın bir yolu var mı, bu durumda ve QItemDelegate ait subclassing yapışmasını olmayabilir şartıyla?
  • QListView'da hangi ItemDelegate öğesinin orijinal olarak QFileSystemModel için kullanıldığını ve nasıl kullanılacağını bilen var mı?
  • Kaynak kodunu almak ve boya yöntemini oradan kopyalamak mümkün mü?

Alt sınıfları kullanan ve descibed davranışını gösteren minimum bir kod. Bir dizgiyi yazabileceği bir QLineEdit kullanır, böylece bu dizeyi içeren tüm dosyalar yeşil renkte vurgulanır.

enter image description here

sadece söz, bu kodu ise, durumu değiştiğinde bir kez o, bir ihtiyacı olan başka bir sorun:

import sys 
from PyQt4 import QtGui, QtCore 


class MyFileViewDelegate(QtGui.QStyledItemDelegate): 
    def __init__(self, parent=None, *args, **kwargs): 
     QtGui.QItemDelegate.__init__(self, parent, *args) 

     self.condition = None 
     self.isMatch = False 

     self.brush_active =   QtGui.QBrush(QtGui.QColor("#79b9ed")) 
     self.brush_active_matched = QtGui.QBrush(QtGui.QColor("#58cd1c")) 
     self.pen =     QtGui.QPen(QtGui.QColor("#414141")) 
     self.pen_matched =   QtGui.QPen(QtGui.QColor("#39c819")) 
     self.pen_active =   QtGui.QPen(QtGui.QColor("#eef2fd")) 
     self.pen_active_matched = QtGui.QPen(QtGui.QColor("#e7fade")) 


    def paint(self, painter, option, index): 
     text = index.data(QtCore.Qt.DisplayRole) 
     self.matchText(text) 

     painter.save() 
     ######## set background 
     painter.setPen(QtGui.QPen(QtCore.Qt.NoPen)) 
     if option.state & QtGui.QStyle.State_Selected: 
      if self.isMatch: 
       painter.setBrush(self.brush_active_matched) 
      else: 
       painter.setBrush(self.brush_active) 

     painter.drawRect(option.rect) 
     ######## set font color 
     if option.state & QtGui.QStyle.State_Selected: 
      if self.isMatch: 
       painter.setPen(self.pen_active_matched) 
      else: 
       painter.setPen(self.pen_active) 
     else: 
      if self.isMatch: 
       painter.setPen(self.pen_matched) 
      else: 
       painter.setPen(self.pen) 

     painter.drawText(option.rect, QtCore.Qt.AlignLeft, text) 

     painter.restore() 

    def matchText(self, filename): 
     # testing condition. In the real case this is much more complicated 
     if (self.condition != None) and (self.condition != "") and (self.condition in filename): 
      self.isMatch = True 
     else: 
      self.isMatch = False 

    def setCondition(self, condition): 
     self.condition = condition 


class MainWidget(QtGui.QWidget): 
    def __init__(self, parent=None, useDelegate = False): 
     super(MainWidget, self).__init__(parent) 
     self.setLayout(QtGui.QVBoxLayout()) 

     self.FolderModel = QtGui.QFileSystemModel() 
     self.FolderModel.setFilter(QtCore.QDir.NoDotAndDotDot | QtCore.QDir.AllDirs) 
     self.FolderModel.setRootPath("") 

     self.FolderView = QtGui.QTreeView(parent=self) 
     self.FolderView.setModel(self.FolderModel) 

     self.FolderView.setHeaderHidden(True) 
     self.FolderView.hideColumn(1) 
     self.FolderView.hideColumn(2) 
     self.FolderView.hideColumn(3) 
     self.FolderView.expanded.connect(self.FolderView.scrollTo) 
     self.FolderView.clicked[QtCore.QModelIndex].connect(self.browserClicked) 

     self.FileModel = QtGui.QFileSystemModel() 
     self.FileModel.setFilter(QtCore.QDir.NoDotAndDotDot | QtCore.QDir.Files) 

     self.FileView = QtGui.QListView(parent=self) 
     self.FileView.setModel(self.FileModel) 

     self.FileViewDelegate = None 
     if useDelegate: 
      self.FileViewDelegate = MyFileViewDelegate() 
      self.FileView.setItemDelegate(self.FileViewDelegate) 

     self.FileView.setSelectionMode( QtGui.QAbstractItemView.ExtendedSelection ) 

     self.LineEdit = QtGui.QLineEdit() 
     self.LineEdit.textChanged.connect(self.changeCondition) 

     # Add Widgets to layout 
     self.layout().addWidget(self.FolderView) 
     self.layout().addWidget(self.FileView) 
     self.layout().addWidget(self.LineEdit) 

    def changeCondition(self, text): 
     if self.FileViewDelegate: 
      self.FileViewDelegate.setCondition(text) 

    def browserClicked(self, index): 
     # the signal passes the index of the clicked item 
     # set the FileView's root_index to the clicked index 
     dir_path = self.FileModel.filePath(index) 
     root_index = self.FileModel.setRootPath(dir_path) 
     self.FileView.setRootIndex(root_index) 


class App(QtGui.QMainWindow): 
    def __init__(self, parent=None, useDelegate=False): 
     super(App, self).__init__(parent) 
     self.central = MainWidget(parent =self, useDelegate=useDelegate) 
     self.setCentralWidget(self.central) 

if __name__=='__main__': 
    app = QtGui.QApplication(sys.argv) 
    thisapp = App(None, True) # set False to view App without custom FileViewDelegate 
    thisapp.show() 
    sys.exit(app.exec_()) 

Bu

o QItemDelegate ile ve sınıflara olmadan nasıl göründüğünü karşılaştırmadır Yeniden boyamayı başlatmak için fareyi QFileView içine hareket ettirin. Bunu yapmak için LineEdit.textChange sinyaline bağlanmak için hangi yuvayı kullanabileceğimi merak ediyorum.

cevap

3

Öğe temsilcisine gerek yoktur. Bu QFileSystemModel ait data yöntemini reimplementing tarafından çok daha basitçe elde edilebilir: Bu mükemmel çalışıyor

class FileSystemModel(QtGui.QFileSystemModel): 
    def __init__(self, *args, **kwargs): 
     super(FileSystemModel, self).__init__(*args, **kwargs) 
     self.condition = None 

    def setCondition(self, condition): 
     self.condition = condition 
     self.dataChanged.emit(QtCore.QModelIndex(), QtCore.QModelIndex()) 

    def data(self, index, role=QtCore.Qt.DisplayRole): 
     if self.condition and role == QtCore.Qt.TextColorRole: 
      text = index.data(QtCore.Qt.DisplayRole) 
      if self.condition in text: 
       return QtGui.QColor("#58cd1c") 
     return super(FileSystemModel, self).data(index, role) 

class MainWidget(QtGui.QWidget): 
    def __init__(self, parent=None, useDelegate = False): 
     super(MainWidget, self).__init__(parent) 
     ... 
     self.FileModel = FileSystemModel(self) 
     ... 

    def changeCondition(self, text): 
     self.FileModel.setCondition(text) 
+0

.Bir çözüm ararken modelin bu tür alt sınıflarını neden bulamadığımı merak ediyorum. Bu genellikle yapılmaz mı, yoksa herhangi bir dezavantajları var mı? – ImportanceOfBeingErnest

+0

@ImportanceOfBeingErnest. Qt, Python'un [TOOWTDI] (http://wiki.python.org/moin/TOOWTDI) yaklaşımını takip etmemekte gibi görünüyor; bu, çoğu zaman belirli problemleri çözmek için birkaç farklı yol sunuyor. Alt sınıflama, muhtemelen en yaygın kullanılan yaklaşımdır, ancak açık bir şekilde, ilgi yöntemlerinin yararlı bir şekilde yeniden kullanılabilir hale getirilip getirilemeyeceğine (yani, sanal metotlar olup olmadığına) bağlıdır. – ekhumoro

İlgili konular