[PYTHON] Beseitigen Sie die Unannehmlichkeiten von QDock Widget mit PySide

QDockWidget ist ein sehr schönes Widget, mit dem Sie Layoutanpassungen dem Benutzer überlassen können. Es ist jedoch auch wahr, dass es viele Orte gibt, an denen ich mich frage: "Kann ich das tun?" (Ich habe das Gefühl, dass Qt im gesamten Standardzustand oft außerhalb der Reichweite von juckenden Stellen liegt.)

Lassen Sie uns die Unannehmlichkeiten mit QDockWidget erhöhen.

Da das Tabbing im letzten Float-Zustand von Qt5.5 unterstützt wird, wird es hier nicht unterstützt. Warten Sie auf den Abschluss von PySide2 für Qt5.

Lösen wir es in der Reihenfolge von oben.

Zeigen Sie ein Symbol in der Titelleiste an (Abandoned)

** Plötzlich verlassen. ** ** **

Mit zunehmender Anzahl von DockWidgets nimmt die Sichtbarkeit ab, welches Dock welche Funktion hat. Es wäre praktisch, wenn das von QDockWidget :: setWindowIcon festgelegte Symbol in der Titelleiste angezeigt würde.

Das scheint aber schwierig.

Zeichnen Sie mit PySide Ihren eigenen Drop Indicator (Realisieren Sie QProxyStyle mit schwarzer Magie)

Hängen Sie das drawControl in die Titelleiste mit dem im obigen Artikel verwendeten ProxyStyle ein.

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)

Das Symbol wird von selbst gezeichnet, der Anzeigebereich wird um das Symbol verschoben und an die Originalzeichnung übergeben. Das Ergebnis ist jedoch wie folgt: Der Hintergrund des Symbolteils ist nicht gefüllt.

2016-12-30_01h49_092.png

Um diese Situation zu vermeiden, habe ich die Qt-Quelle gelesen, sie ist jedoch fest codiert. Wenn Sie dies tun, müssen Sie alle Titelleisten selbst zeichnen. In jedem Fall handelt es sich bei der Titelleiste im Float-Status nach einer harten Implementierung um eine separate Implementierung. Daher muss diese ebenfalls neu implementiert werden.

Ich gab auf, weil es zu wenig Belohnungen für meine harte Arbeit gab.

Das Symbol wird auf der Registerkarte nicht angezeigt, wenn es mit Registerkarten versehen ist

Um das Symbol in der Titelleiste anzuzeigen, zeigen Sie das Symbol im Dock an. Es ist jedoch nicht gut, dass das Symbol nicht auf der Registerkarte mit Registerkarten angezeigt wird. Da der Inhalt des Hundes nicht sichtbar ist, kann er nur von den Zeichen auf der Registerkarte erkannt werden, was ein großes Problem bei der Sichtbarkeit darstellt.

Wenn QDockWidget mit Registerkarten versehen ist, wird die Registerkarte in QTabBar in QMainWindow gespeichert. Diese Registerkarte und das QDock-Widget sind jedoch völlig getrennte Dinge.

Lösen wir es also etwas grob. Schauen Sie sich den folgenden Code an.

#! 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()

Das Ausführungsergebnis lautet wie folgt und das Symbol wird auf der Registerkarte DockWidget angezeigt.

2016-12-30_02h31_53.png

Ich überprüfe jedes Mal, wenn das Layout des QDockWidget geändert wird, die Registerkarte QTabBar unter dem Hauptfenster und setze auf der Registerkarte ein Symbol mit demselben Titelnamen.

Es ist eine Brute-Force-Methode, aber soweit ich die Qt-Quelle lese, scheint es keine andere Lösung zu geben. Der Layoutzeiger wird in QTabBar :: tabData gespeichert, aber das Anwenderprogramm kann das QDockWidget nicht aus dem Zeiger ermitteln. Auf der Seite des Anwenderprogramms gibt es nur ein Element, das nur den Registerkartennamen und den Titelnamen von QDockWidget verbindet.

Die Symbolleiste kann nicht in QDockWidget platziert werden

Die Symbolleiste des Hauptfensters kann nicht in einem QDock-Widget platziert werden, aber jedes QDock-Widget kann eine separate Symbolleiste haben.

#! 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

Sie können sehen, dass jedes der beiden QDock-Widgets über eine Symbolleiste verfügt.

In der Symbolleiste kann nur QMainWindow platziert werden. Daher verfügt jedes QDockWidget als untergeordnetes Element über ein QMainWindow, und die Symbolleiste wird dort platziert.

Zusammenfassung

Qt ist ein großartiges GUI-Tool, aber der Status des Elements ist unpraktisch.

Da die Zeichnung vollständig von Qt erstellt wird, kann alles frei implementiert werden. Es gibt jedoch zu viele Situationen, die der Benutzer mit einer kleinen Erweiterung vollständig implementieren muss. (Dies ist eine Menge harter Codierung ohne Erweiterbarkeit, anstatt dass das Qt-Design zu lasch ist.)

Wenn Sie der Meinung sind, dass es eine intelligentere Lösung gibt, nur weil Ihnen Kenntnisse fehlen, unterrichten Sie uns bitte.

Recommended Posts

Beseitigen Sie die Unannehmlichkeiten von QDock Widget mit PySide
Richten Sie die Größe der Farbleiste an der Matplotlib aus
Überprüfen Sie die Existenz der Datei mit Python
Die dritte Nacht der Runde mit für
Die zweite Nacht der Runde mit für
Zählen Sie die Anzahl der Zeichen mit Echo
Die Geschichte des tiefen Lernens mit TPU
Hinweis: Bereiten Sie die Umgebung von CmdStanPy mit Docker vor
Bereiten Sie die Ausführungsumgebung von Python3 mit Docker vor
2016 Todai Mathematik mit Python gelöst
[Hinweis] Exportieren Sie das HTML der Site mit Python.
Erhöhen Sie die Schriftgröße des Diagramms mit matplotlib
Überprüfen Sie das Datum der Flaggenpflicht mit Python
Fordern Sie den Turm von Hanoi mit Wiederholungen + Stapel heraus
Schreiben Sie den Namen des Tags mit dem Namespace in lxml neu
Füllen Sie die Breite des Jupyter-Notizbuchs, um den Browser zu füllen
Prognostizieren Sie die zweite Runde des Sommers 2016 mit scikit-learn
Entleere den Inhalt der Redis-Datenbank mit Lua
Erstellen Sie mit Python + Qt (PySide) ein farbspezifisches Widget.
Finden Sie den Tag nach Datum / Uhrzeit heraus
Die Basis der Graphentheorie mit Matplotlib-Animation
GUI-Erstellung mit Pyside Teil 2 <Verwendung der Klasse>
Visualisieren Sie das Verhalten des Sortieralgorithmus mit matplotlib
Konvertieren Sie den Zeichencode der Datei mit Python3
[Python] Bestimmen Sie den Typ der Iris mit SVM
Extrahieren Sie die Tabelle der Bilddateien mit OneDrive & Python
Ganz rechts Koordinaten des Etiketts mit tkinter erstellt
Die Geschichte des Stoppens des Produktionsdienstes mit dem Befehl hostname
Lerne Nim mit Python (ab Anfang des Jahres).
Berechnen Sie die Summe der eindeutigen Werte durch Pandas-Kreuztabellen
Spielen Sie mit der Implementierung der Pythonista 3-Benutzeroberfläche [Super Super Primer]
Fügen Sie mit Matplotlib Informationen am unteren Rand der Abbildung hinzu
Berechnen Sie den Gesamtwert mehrerer Spalten mit awk
Machen Sie LCD-Screenshots mit Python-LEGO Mindstorms
Visualisieren Sie den Bereich der internen und externen Einfügungen mit Python
Nehmen Sie den Wert des SwitchBot-Thermo-Hygrometers mit Raspberry Pi
Sagen Sie die Anzahl der mit COVID-19 infizierten Personen mit Prophet voraus
Umschalten der Bot-Thermo-Hygrometer-Werte mit Raspberry Pi
Finden Sie den Speicherort der mit pip installierten Pakete heraus
Prognostizieren Sie das Geschlecht von Twitter-Nutzern durch maschinelles Lernen
Versuchen Sie, den Inhalt von Word mit Golang zu erhalten
Visualisieren Sie das charakteristische Vokabular eines Dokuments mit D3.js.
Ich habe die Leistung von 1 Million Dokumenten mit mongoDB gemessen
Vorbereiten der Ausführungsumgebung von PyTorch mit Docker November 2019
Lesen Sie die Leistung des Smart Meters mit M5StickC (BP35C0-J11-T01 Edition) ab.
Verwalten Sie die Paketversionsnummer von require.txt mit pip-tools
Zusammenfassung des grundlegenden Ablaufs des maschinellen Lernens mit Python
Aufzeichnung der ersten Herausforderung des maschinellen Lernens mit Keras
Holen Sie sich mit Python den Betriebsstatus von JR West
Visualisieren Sie mit OpenCV den Wertschätzungsstatus von Kunstwerken
[Für Anfänger] Quantifizieren Sie die Ähnlichkeit von Sätzen mit TF-IDF
Skript zum Ändern der Klanglänge mit REAPER
Passen Sie das Verhältnis mehrerer Zahlen mit der Rasterspezifikation von Matplotlib an
Berechnen Sie das Produkt von Matrizen mit einem Zeichenausdruck?