Lors du changement de la couleur d'arrière-plan d'un widget avec PySide, l'indicateur de chute (affichage de l'endroit où déposer lors du glisser-déposer) peut être difficile à voir. Je veux dessiner le mien pour faire ressortir l'Indicateur.
Cependant, les choses ne sont pas faciles et StyleSheet n'a pas de paramètre d'indicateur de chute.
QProxyStyle est utilisé pour dessiner l'indicateur de chute indépendamment dans Qt, mais QProxyStyle n'existe pas dans PySide et PyQt.
Par conséquent, piratez PySide pour intercepter le dessin de Drop Indicator. De plus, cette méthode n'est pas une magie noire légitime, et nous ne pouvons garantir qu'elle sera efficace dans le futur PySide.
Tout d'abord, volons le dessin de manière légitime.
Tout d'abord, pensons à une méthode légitime.
C'est un moyen d'étendre vous-même la classe QStyle et de remplacer la méthode QStyle :: drawPrimitive. Puisque mon environnement est Windows, j'hérite de QWindowsStyle.
class MyWindowsStyle(QWindowsStyle):
def drawPrimitive(self, element, option, painter, widget):
if element == QStyle.PE_IndicatorItemViewItemDrop:
pen = QPen(Qt.red)
pen.setWidth(2)
painter.setPen(pen)
if not option.rect.isNull():
painter.drawRect(option.rect)
return
super(MyWindowsStyle, self).drawPrimitive(element, option, painter, widget)
Dans l'exemple ci-dessus, l'indicateur de chute est rouge et le cadre est épais. Définissez cette classe de style avec QApplication :: setStyle.
my_style = MyWindowsStyle(parent_widget)
QApplication.setStyle(my_style)
Cela semble avoir fonctionné, mais dans l'ensemble, cela semble démodé.
Dans la version Windows de PySide (Qt), le style standard est QWindowsVistaStyle au lieu de QWindowStyle. Cependant, QWindowsVistaStyle est un style de plugin chargé dynamiquement, donc l'héritage de classe n'est pas possible. De plus, comme il hérite d'une classe de style spécifique, il aura le même aspect et la même sensation sur Mac et Linux. Si ces inconvénients ne vous dérangent pas, nous vous recommandons cette méthode.
Utilisons maintenant la magie noire pour voler le dessin de style QWindows Vista.
Commencez par créer une instance QWindowsVistaStyle. Utilisez la classe QStyleFactory pour générer des styles.
vista_style = QStyleFactory.create("windowsvista")
Vous venez de créer une instance QWindowsVistaStyle.
En passant, vérifiez la classe de style standard et le nom de la clé (chaîne de caractères transmise à QStyleFactory.create) de chaque environnement comme suit.
QApplication.style().metaObject().className()
>>> QWindowsVistaStyle
QApplication.style().objectName()
>>> windowsvista
Créez une classe Proxy contenant des instances de style.
class ProxyStyle(QCommonStyle):
TranslateMethods = [
'drawComplexControl', 'drawControl', 'drawItemText', 'generatedIconPixmap',
'hitTestComplexControl', 'pixelMetric', 'polish', 'sizeFromContents',
'sizeFromContents', 'standardPixmap', 'styleHint', 'styleHint',
'subControlRect', 'subElementRect', 'unpolish'
]
def __init__(self, style, parent=None):
super(ProxyStyle, self).__init__(parent)
self._style = style
for method_name in self.TranslateMethods:
setattr(self, method_name, getattr(self._style, method_name))
def drawPrimitive(self, element, option, painter, widget):
if element == QStyle.PE_IndicatorItemViewItemDrop:
pen = QPen(Qt.red)
pen.setWidth(2)
painter.setPen(pen)
if not option.rect.isNull():
painter.drawRect(option.rect)
return
self._style.drawPrimitive(element, option, painter, widget)
Comme vous pouvez le voir, la délégation se fait de manière forcée et boueuse.
À propos, l'objet PySide ne peut pas utiliser l'astuce de délégation de
getattr```.
QProxyStyle est implémenté avec la magie noire de force brute.
Proxy dynamiquement les instances de style de cette classe et définissez-les comme styles dans QApplication.
proxy_style = ProxyStyle(vista_style)
QApplication.setStyle(proxy_style)
Cela semble avoir fonctionné. Même si vous utilisez StyleSheet ensemble et rendez l'arrière-plan gris comme indiqué ci-dessous, cela fonctionne sans problème.
tree_view.setStyleSheet("QTreeView { background-color: gray }")
Cette méthode n'est pas du tout élégante.
Il existe également une méthode pour remplacer le paintEvent de la vue et tout dessiner par vous-même, mais c'est très gênant car il est nécessaire de changer le dessin pour chaque type de vue. Si possible, j'aimerais survivre en définissant le style.
S'il y a un meilleur moyen, apprenez-moi s'il vous plaît.