[PYTHON] Éliminez les inconvénients du widget QDock avec PySide

QDockWidget est un widget très agréable qui vous permet de laisser les ajustements de mise en page à l'utilisateur. Cependant, il est également vrai qu'il y a de nombreux endroits où je me demande: "Puis-je faire ça?" (Je pense que Qt est souvent hors de portée des endroits qui démangent dans l'état standard dans son ensemble)

Soulignons les inconvénients avec QDockWidget.

--L'icône n'est pas affichée dans la barre de titre

Comme la tabulation dans le dernier état Float est prise en charge par Qt5.5, elle n'est pas prise en charge ici. Attendez la fin de PySide2 pour Qt5.

Résolvons-le dans l'ordre du haut.

Afficher une icône dans la barre de titre (abandonné)

** Soudainement abandonné. ** **

À mesure que le nombre de DockWidgets augmente, la visibilité de quel Dock a quelle fonction diminue. Ce serait pratique si l'icône définie par QDockWidget :: setWindowIcon est affichée dans la barre de titre.

Mais cela semble difficile.

Dessinez votre propre indicateur de chute avec PySide (Réalisez QProxyStyle avec la magie noire)

Accrochez le drawControl dans la barre de titre avec le ProxyStyle utilisé dans l'article ci-dessus.

def drawControl(self, element, option, painter, widget):
    if element == QStyle.CE_DockWidgetTitle:
        width = self.pixelMetric(QStyle.PM_ToolBarIconSize)
        margin = self.pixelMetric(QStyle.PM_DockWidgetTitleMargin)

        painter.drawPixmap(margin, margin, widget.windowIcon().pixmap(QSize(width / 2, width / 2)))
        option.rect.adjust(width, 0, 0, 0)
    return self._style.drawControl(element, option, painter, widget)

L'icône est dessinée par elle-même, la plage d'affichage est décalée par l'icône et elle est transmise au dessin d'origine. Cependant, le résultat est le suivant: L'arrière-plan de la partie icône n'est pas rempli.

2016-12-30_01h49_092.png

Afin d'éviter cette situation, j'ai lu la source Qt, mais elle est codée en dur. Si vous le faites, vous devez dessiner vous-même toutes les barres de titre. Dans tous les cas, la barre de titre dans l'état Float est une implémentation distincte après une implémentation matérielle, il est donc nécessaire de la réimplémenter également.

J'ai abandonné parce qu'il y avait trop peu de récompenses pour mon travail acharné.

Iconon n'est pas affiché sur l'onglet lorsqu'il est tabulé

Pour afficher l'icône sur la barre de titre, affichez l'icône à l'intérieur du dock. Cependant, il n'est pas bon que l'icône ne s'affiche pas sur l'onglet à onglets. Comme le contenu du chien ne peut pas être vu, il ne peut être reconnu que par les personnages de l'onglet, ce qui pose un gros problème de visibilité.

Lorsque QDockWidget est tabulé, l'onglet est stocké dans QTabBar dans QMainWindow. Mais cet onglet et le widget QDock sont des éléments complètement séparés.

Alors résolvons-le de manière un peu approximative, jetez un œil au code ci-dessous.

#! usr/bin/python
# -*- coding: utf-8 -*-
from __future__ import unicode_literals, print_function, absolute_import
import sys
from PySide.QtCore import *
from PySide.QtGui import *


def main():
    app = QApplication(sys.argv)
    main_window = QMainWindow()

    warning_icon = QApplication.style().standardIcon(QStyle.SP_MessageBoxWarning)
    critical_icon = QApplication.style().standardIcon(QStyle.SP_MessageBoxCritical)

    dock_1 = QDockWidget("warning", main_window)
    dock_1.setWindowIcon(warning_icon)

    dock_2 = QDockWidget("critical", main_window)
    dock_2.setWindowIcon(critical_icon)

    main_window.addDockWidget(Qt.LeftDockWidgetArea, dock_1)
    main_window.addDockWidget(Qt.RightDockWidgetArea, dock_2)

    def onLocationChanged(area):
        icon_dict = {}
        for _dock in main_window.findChildren(QDockWidget):
            icon_dict[_dock.windowTitle()] = _dock.windowIcon()

        for tab_bar in main_window.findChildren(QTabBar):
            for idx in range(tab_bar.count()):
                if tab_bar.tabText(idx) in icon_dict:
                    tab_bar.setTabIcon(idx, icon_dict[tab_bar.tabText(idx)])

    for dock in main_window.findChildren(QDockWidget):
        dock.dockLocationChanged.connect(onLocationChanged)
    onLocationChanged(0)

    main_window.show()
    app.exec_()


if __name__ == "__main__":
    main()

Le résultat de l'exécution est le suivant et l'icône s'affiche sur l'onglet DockWidget.

2016-12-30_02h31_53.png

Ce que je fais, c'est vérifier l'onglet QTabBar sous la fenêtre principale chaque fois que la mise en page du QDockWidget est modifiée, et définir une icône sur l'onglet avec le même nom de titre.

C'est une méthode de force brute, mais pour autant que je sache la source Qt, il ne semble pas y avoir d'autre solution. Le pointeur de disposition est stocké dans QTabBar :: tabData, mais le programme utilisateur ne peut pas déterminer le QDockWidget à partir du pointeur. Du côté du programme utilisateur, il n'y a qu'un élément qui relie uniquement le nom de l'onglet et le nom du titre de QDockWidget.

Impossible de placer la barre d'outils dans QDockWidget

La barre d'outils de la fenêtre principale ne peut pas être placée dans un widget QDock, mais chaque widget QDock peut avoir une barre d'outils distincte.

#! usr/bin/python
# -*- coding: utf-8 -*-
from __future__ import unicode_literals, print_function, absolute_import
import sys
from PySide.QtCore import *
from PySide.QtGui import *


def main():
    app = QApplication(sys.argv)
    main_window = QMainWindow()

    home_icon = QApplication.style().standardIcon(QStyle.SP_DirHomeIcon)
    drive_icon = QApplication.style().standardIcon(QStyle.SP_DriveDVDIcon)
    home_action = QAction(home_icon, "Home", main_window)
    drive_action = QAction(drive_icon, "Drive", main_window)

    dock_1 = QDockWidget("warning", main_window)
    dock_2 = QDockWidget("critical", main_window)
    main_window.addDockWidget(Qt.LeftDockWidgetArea, dock_1)
    main_window.addDockWidget(Qt.RightDockWidgetArea, dock_2)

    def create_dock_toolbar(dock):
        __main_window = QMainWindow()
        __main_window.setParent(dock)
        dock.setWidget(__main_window)
        return __main_window

    _main_window = create_dock_toolbar(dock_1)
    bar = QToolBar(_main_window)
    bar.addActions([home_action, drive_action])
    _main_window.addToolBar(bar)

    _main_window = create_dock_toolbar(dock_2)
    bar = QToolBar(_main_window)
    bar.addActions([home_action, drive_action])
    _main_window.addToolBar(bar)

    main_window.show()
    app.exec_()


if __name__ == "__main__":
    main()
2016-12-30_02h48_55.png

Vous pouvez voir que chacun des deux widgets QDock possède une barre d'outils.

Seul QMainWindow peut être placé sur la barre d'outils. Ainsi, chaque QDockWidget a un QMainWindow comme enfant, et la barre d'outils y est placée.

Résumé

Qt est un excellent outil graphique, mais l'état de l'élément n'est pas pratique.

Le dessin étant entièrement réalisé par Qt, tout peut être librement implémenté. Cependant, il y a trop de situations que l'utilisateur doit mettre en œuvre intégralement avec un peu d'expansion. (C'est beaucoup de codage en dur sans extensibilité plutôt que la conception Qt étant trop laxiste)

Si vous pensez qu'il existe une solution plus intelligente simplement parce que vous manquez de connaissances, veuillez nous en informer.

Recommended Posts

Éliminez les inconvénients du widget QDock avec PySide
Alignez la taille de la barre de couleurs avec matplotlib
Vérifier l'existence du fichier avec python
La troisième nuit de la boucle avec pour
La deuxième nuit de la boucle avec pour
Compter le nombre de caractères avec écho
L'histoire de l'apprentissage profond avec TPU
Remarque: préparez l'environnement de CmdStanPy avec docker
Préparer l'environnement d'exécution de Python3 avec Docker
Mathématiques Todai 2016 résolues avec Python
[Note] Exportez le html du site avec python.
Augmentez la taille de la police du graphique avec matplotlib
Vérifiez la date du devoir de drapeau avec Python
Défiez la tour de Hanoi avec recurs + stack
Renommer la balise avec un espace de noms en lxml
Remplissez la largeur du bloc-notes Jupyter pour remplir le navigateur
Prédisez le deuxième tour de l'été 2016 avec scikit-learn
Vider le contenu de la base de données redis avec lua
Créer un widget avec une couleur spécifiée avec Python + Qt (PySide)
Découvrez le jour par date / heure
La base de la théorie des graphes avec l'animation matplotlib
Création de l'interface graphique avec Pyside Partie 2 <Utilisation de la classe>
Visualisez le comportement de l'algorithme de tri avec matplotlib
Convertir le code de caractère du fichier avec Python3
[Python] Déterminez le type d'iris avec SVM
Extraire le tableau des fichiers image avec OneDrive et Python
Coordonnées les plus à droite de l'étiquette faite avec tkinter
L'histoire de l'arrêt du service de production avec la commande hostname
Apprenez Nim avec Python (dès le début de l'année).
Calculer la somme des valeurs uniques par tabulation croisée des pandas
Jouez avec l'implémentation de l'interface utilisateur de Pythonista 3 [Super Super Primer]
Ajoutez des informations au bas de la figure avec Matplotlib
Calculez la valeur totale de plusieurs colonnes avec awk
Prenez des captures d'écran LCD avec Python-LEGO Mindstorms
Visualisez la gamme d'insertions internes et externes avec python
Prenez la valeur du thermo-hygromètre SwitchBot avec Raspberry Pi
Prédire le nombre de personnes infectées par COVID-19 avec Prophet
Changer les valeurs du thermo-hygromètre Bot avec Raspberry Pi
Découvrez l'emplacement des packages installés avec pip
Prédire le sexe des utilisateurs de Twitter grâce à l'apprentissage automatique
Essayez d'obtenir le contenu de Word avec Golang
Visualisez le vocabulaire caractéristique d'un document avec D3.js
J'ai mesuré les performances d'un million de documents avec mongoDB
Préparation de l'environnement d'exécution de PyTorch avec Docker Novembre 2019
Lisez la puissance du compteur intelligent avec M5StickC (édition BP35C0-J11-T01)
Gérez le numéro de version du package de requirements.txt avec pip-tools
Résumé du flux de base de l'apprentissage automatique avec Python
Bilan du premier défi du machine learning avec Keras
Obtenez l'état de fonctionnement de JR West avec Python
Visualisez le statut d'appréciation des œuvres d'art avec OpenCV
[Pour les débutants] Quantifier la similitude des phrases avec TF-IDF
Script pour changer la longueur du son avec REAPER
Ajustez le rapport de plusieurs chiffres avec le gridspec de Matplotlib
Calculer le produit des matrices avec une expression de caractère?