Werkzeugleiste

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
Antworten
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

Hallo,

ich bin gerade dabei, eine ToolBar auf mein MainWindow hinzuzufügen. Und ich bin ähnlich vorgegangen als würde ich eine Menüleiste hinzufügen. Ich habe eine '.py-Datei für die ToolBar angelegt. Die Datei sieht wie folgt aus:

MDIForm_ToolBar.py

Code: Alles auswählen

imort sys
from PyQt4.QtGui import QAction, QToolBar, QIcon
from PyQt4 import QtGui, QtCore

class ToolBarLeiste(QToolBar):
    def __init__ (self, parent=None):
        QToolBar.__init__(self, parent)

        # Hier wird der Path des Icons angegeben, um dem Button der ToolBar ein Icon zu geben
        self.DoShowToolBarFilmButton = QAction(QIcon('icons/open.png'), 'Film hinzufügen', self)
        self.DoShowToolBarFilmButton.setShortcut('Ctrl+Q')

        # An dieser Stelle wird eine Werkzeugleiste/ToolBar erzeugt.
        self.DoShowToolBar = self.addToolBar('Film hinzufügen')
        self.DoShowToolBar.addAction(self.DoShowTooBarFilmButton)
Hier habe ich besonders darauf geachtet, dass DoShowToolBar und DoShowToolBarFilmButton Attribute der ToolBarLeiste-Klasse sind, und keine Variablen.

---------
MDIForm.py

Code: Alles auswählen

# -*- coding: cp1252 -*-
import sys 
from PyQt4.QtGui import QMainWindow, QApplication, QAction, QMenuBar
from PyQt4.QtCore import SIGNAL, SLOT

from MDIForm_Menue import MenueLeiste

from MDIForm_ToolBar import ToolBarLeiste
  
class MDIFormular(QMainWindow):
    # Vererbung aktivieren, angeben, dass es keine Elternform hat
    def __init__ (self, parent=None): 
        QMainWindow.__init__(self, parent)

        self.setWindowTitle(' Xarphus Build 0.1')

        self.statusBar().showMessage('Ready')
        
        # Menüleiste 
        self.MNUL_Verwaltung = MenueLeiste()
        self.setMenuBar(self.MNUL_Verwaltung)

        self.MNUL_Verwaltung.DoShowmnuClose.triggered.connect(self.MnuCloseMain)
        
       # Werkzeugleiste
        self.DoShowToolBar = ToolBarLeiste()
        self.toolBarArea(self.DoShowToolBar) 
        
    def MnuCloseMain(self): 
        print "Ihr Programm wurde soeben erfolgreich beendet."
        self.close()
Wie ihr seht, habe ich in der MDIForm.py-Datei die Klasse ToolBarLeiste aus der Datei MDIForm_ToolBar.py importiert. Und ich habe die ToolBarLeiste-Klasse der Klasse MDIFormular hinzugefügt.

Starte ich das ganze einmal, kommt folgende (für mich verwirrende) Fehlermeldung:
Traceback (most recent call last):
File "D:\Dan\Python\Xarphus.py", line 3, in <module>
from Xarphus.MDIForm import MDIFormular
File "D:\Dan\Python\Xarphus\MDIForm.py", line 79, in <module>
MDIWindow = MDIFormular()
File "D:\Dan\Python\Xarphus\MDIForm.py", line 56, in __init__
self.DoShowToolBar = ToolBarLeiste()
File "D:\Dan\Python\Xarphus\MDIForm_ToolBar.py", line 21, in __init__
self.DoShowToolBar = self.addToolBar('Film')
AttributeError: 'ToolBarLeiste' object has no attribute 'addToolBar'
Die Fehlermeldung besagt, dass die Klasse "ToolBarLeiste" diesen "addToolBar" nicht als Attribut kennt. Komisch ist ja, wie man sehen kannt, dass ich sie dennoch als Attribut gekennzeichnet habe. Demzufolge dürfte die Klasse nicht so tun, als sei hier ein Attribut völlig aus dem Nichts erschienen, die er nicht als solches kennt. Falls ihr euch fragt, wie ich in Zeile 46 auf "toolBarArea" gekommen bin. Ich habe auf dieser Seite (http://qt-project.org/doc/qt-4.8/qmainwindow.html) unter "QMainWindow Class Reference" nach einer Methode gesucht. Dort habe ich auch für die Menüleiste die Methode "setMenuBar" gefunden.

Gruß
Sophus
Benutzeravatar
Madmartigan
User
Beiträge: 200
Registriert: Donnerstag 18. Juli 2013, 07:59
Wohnort: Berlin

QToolBar besitzt keine Methode addToolBar(). Das ist eine Methode von QMainWindow.
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

Madmartigan hat geschrieben:QToolBar besitzt keine Methode addToolBar(). Das ist eine Methode von QMainWindow.
Stimmt. Ich habe nochmal eben auf der Seite (http://qt-project.org/doc/qt-4.8/qtoolbar.html) nachgesehen. Dann bedeutet das für mich, dass ich ToolBar nicht auslagern kann, sondern diese in der Datei MDIForm.py erzeugen muss?
Sirius3
User
Beiträge: 17745
Registriert: Sonntag 21. Oktober 2012, 17:20

Was soll denn das addToolBar Deiner Meinung nach an dieser Stelle machen? ToolBarLeiste ist doch schon eine Toolbar. Und die Toolbar erzeugen tust Du in Zeile 26 von MDIFormular.
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

Sirius3 hat geschrieben:Was soll denn das addToolBar Deiner Meinung nach an dieser Stelle machen? ToolBarLeiste ist doch schon eine Toolbar. Und die Toolbar erzeugen tust Du in Zeile 26 von MDIFormular.
Ich bin so ähnlich vorgegangen wie beim Erzeugen einer Menüleiste, die ich auch ausgelagert habe:

MDIForm_Menue.py

Code: Alles auswählen

[...]
        # Eine eigenständige Menuleiste wird erzeugt.
        self.MNUL_Verwaltung = self.addMenu('&Verwaltung')

        # Menüpunk
        self.DoShowmnuFilm = self.MNUL_Verwaltung.addMenu("Filme")
        # Untermenü
        self.FilmAdd = self.DoShowmnuFilm.addAction("Film hinzufügen")
        self.FilmAdd.setStatusTip("Einen neuen Film hinzufügen")
        self.FilmAdd.setShortcut("Ctrl+F")
       [...]
Und dieses Prinzip der Menuleiste übernahm ich beim Erzeugen der Werkzeugleiste. Denn wie bei der Menuleiste habe ich ebenfalls eine Klasse erstellt.

MDIForm_ToolBar.py

Code: Alles auswählen

[...]
        # An dieser Stelle wird eine Werkzeugleiste erzeugt.
        self.DoShowToolBarFilmButton = QAction(QIcon('icons/open.png'), 'Film', self)

        self.DoShowToolBar = self.addToolBar('Film')
        self.DoShowToolBarFilmButton.addAction(self.DoShowToolBarFilmButton)
        [...]
Und da ich beim Erzeugen der Menuleiste "addMenu" verwende, wollte ich mit "addToolBar" so ähnlich verfahren.
Benutzeravatar
Madmartigan
User
Beiträge: 200
Registriert: Donnerstag 18. Juli 2013, 07:59
Wohnort: Berlin

Sophus hat geschrieben:Und dieses Prinzip der Menuleiste übernahm ich beim Erzeugen der Werkzeugleiste
Und da steckt leider wieder das Problem, einfach übernehmen ist selten die richtige Entscheidung. Während QMenu durchaus eine Methode addMenu() besitzt, muss das äquivalente Gegenstück nicht zwangsweise für andere Widgets existieren. Sieh dir einfach die Klassendokumentationen genauer an, dann siehst du sowas bereits bevor der Fehler auftritt.
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

Madmartigan hat geschrieben:
Sophus hat geschrieben:Und dieses Prinzip der Menuleiste übernahm ich beim Erzeugen der Werkzeugleiste
Und da steckt leider wieder das Problem, einfach übernehmen ist selten die richtige Entscheidung. Während QMenu durchaus eine Methode addMenu() besitzt, muss das äquivalente Gegenstück nicht zwangsweise für andere Widgets existieren. Sieh dir einfach die Klassendokumentationen genauer an, dann siehst du sowas bereits bevor der Fehler auftritt.
Jap, beim Blick in die lassen-Referenzen ist mir das bewusst geworden. Dann kann ich ToolBar nicht auslagern und muss sie wohl oder übel in meine Hauptdatei "MDIForm.py" erzeugen. Das klappt ja auch alles wunderbar.
Benutzeravatar
Madmartigan
User
Beiträge: 200
Registriert: Donnerstag 18. Juli 2013, 07:59
Wohnort: Berlin

Ich sehe zwar noch nicht wo genau der Vorteil jetzt zu finden ist, die Toolbar als separate Klasse anzulegen, aber das heißt nicht, dass du das nicht machen kannst. Du darfst eben nur keine Methoden aufrufen wollen, die der Klasse nicht anheim sind. Deine Toolbar-Klasse kann sich doch selbst aufbauen, du musst nur addToolBar() an der richtigen Stelle respektive in der Instanz des QMainWindow aufrufen.

Etwas unschön und dennoch machbar wäre, wenn du dem Konstruktor der Toolbar Klasse das parent, also in dem Fall eine Instanz des QMainWindow, als Parameter übergibst. Dann kannst du auf diesen Parameter bequem addToolBar() aufrufen, ohne anderweitig aus dem Hauptfenster Code ausführen zu müssen. Das funktioniert natürlich nur, wenn parent vom Typ QMainWindow ist, anderenfalls wird das fehlschlagen. Ich würde es auch nicht empfehlen, aber zumindest erwähnen kann man es ja.
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

Madmartigan hat geschrieben:Ich sehe zwar noch nicht wo genau der Vorteil jetzt zu finden ist, die Toolbar als separate Klasse anzulegen, aber das heißt nicht, dass du das nicht machen kannst. Du darfst eben nur keine Methoden aufrufen wollen, die der Klasse nicht anheim sind. Deine Toolbar-Klasse kann sich doch selbst aufbauen, du musst nur addToolBar() an der richtigen Stelle respektive in der Instanz des QMainWindow aufrufen.

Etwas unschön und dennoch machbar wäre, wenn du dem Konstruktor der Toolbar Klasse das parent, also in dem Fall eine Instanz des QMainWindow, als Parameter übergibst. Dann kannst du auf diesen Parameter bequem addToolBar() aufrufen, ohne anderweitig aus dem Hauptfenster Code ausführen zu müssen. Das funktioniert natürlich nur, wenn parent vom Typ QMainWindow ist, anderenfalls wird das fehlschlagen. Ich würde es auch nicht empfehlen, aber zumindest erwähnen kann man es ja.
Der Vorteil? Du sagtest selbst so schön: "NOCH" nicht. Ich möchte zu gerne lernen, wie ich mit Dateien, Klassen und Funkionen umgehen soll, wenn ich diese auslagere und deswegen importieren möchte. Alles in eine Datei zu schreiben ist vielleicht im geringen Maßen auch vertretbar, aber ich möchte gerne alles auslagern, damit nicht nachher in meiner Hauptdatei so viele Code-Zeilen ansammeln. Aber vordergründig hat es einfach für mich einen Lerneffekt
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

Madmartigan hat geschrieben:Du darfst eben nur keine Methoden aufrufen wollen, die der Klasse nicht anheim sind. Deine Toolbar-Klasse kann sich doch selbst aufbauen, du musst nur addToolBar() an der richtigen Stelle respektive in der Instanz des QMainWindow aufrufen.
"An der richtigen Stelle." Das ist eine Aussage, die auf alles im alltäglichen Leben passt, und somit inhaltsleer ist. Da ich leider nichts konkretes bekam, habe ich natürlich herumprobiert. Mein folgender Versuch sah bis jetzt wie folgt aus:

MDIForm.py

Code: Alles auswählen

[...]
class MDIFormular(QMainWindow):
    # Vererbung aktivieren, angeben, dass es keine Elternform hat
    def __init__ (self, parent=None): 
        QMainWindow.__init__(self, parent)
[...]
        self.DoShowToolBar = ToolBarLeiste() 
        self.DoShowToolBar = self.addToolBar("MyToolBar")
        self.toolBarArea(self.DoShowToolBar)
[...]
In Zeile füge ich die Klasse ToolBarLeiste der Klasse MDIFormular hinzu. In Zeile 8 füge ich durch die Methode addToolBar die Werzeugleiste hinzu. Und in Zeile 9 wollte ich durch die Methode toolBarArea das Attribut DoShowToolBar in einem Parameter übergeben. Starte ich das Ganze, kommt natürlich keine Fehlermeldung, die Werzeugleiste ist vorhanden, aber keine ToolBarButtons, die ich in einer separaten Datei erzeugt habe. Es folgt meine Fehlermeldung, aber meine ToolBar ist natürlich immer noch nicht vollständig zu sehen. Wo liegt der Hund konkret begraben?

MDIForm_ToolBar.py

Code: Alles auswählen

class ToolBarLeiste(QToolBar ):
    def __init__ (self, parent=None):
        QToolBar .__init__(self, parent)

        # An dieser Stelle erzeugen wir eine Werkzeugleiste.
        self.DoShowToolBarFilmButton = QAction(QIcon(path.join('Xarphus\Images\bluebook.png')), 'Film hinzufügen', self)

        self.DoShowToolBar = self.addAction(self.DoShowToolBarFilmButton)
        [...]
Sirius3
User
Beiträge: 17745
Registriert: Sonntag 21. Oktober 2012, 17:20

@Sophus: Was macht Zeile 7 und was Zeile 8? Und wenn Du die Dokumentation gelesen hättest, wüßtest Du, dass Zeile 9 absolut gar nichts macht, weil sie nur etwas abfragt, Dich aber das Ergebnis gar nicht interessiert.
Also bleibt nur Zeile 8 übrig, die was wirkungsvolles tut. Und Du wunderst Dich, dass Deine Toolbar leer ist?
Benutzeravatar
Madmartigan
User
Beiträge: 200
Registriert: Donnerstag 18. Juli 2013, 07:59
Wohnort: Berlin

Sophus hat geschrieben: "An der richtigen Stelle." Das ist eine Aussage, die auf alles im alltäglichen Leben passt, und somit inhaltsleer ist. Da ich leider nichts konkretes bekam, habe ich natürlich herumprobiert.
Meine Antwort war inhaltsleer und unkonkret ... Undank ist der Welten Lohn, was?

Instanz von QMainWindow <- das IST die richtige Stelle!
Aber das war dir sicherlich nicht konkret genug, das nächste Mal werde ich dir die Zeilennummer diktieren.

Du bist doch schief gewickelt, Jungchen.
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

Madmartigan hat geschrieben:Du bist doch schief gewickelt, Jungchen.
Das Forum dient zum regen Austausch über Programmierbelange, nicht um Leute dumm zu machen. Bitte respektiere das. Danke.
Benutzeravatar
Madmartigan
User
Beiträge: 200
Registriert: Donnerstag 18. Juli 2013, 07:59
Wohnort: Berlin

jerch hat geschrieben:
Madmartigan hat geschrieben:Du bist doch schief gewickelt, Jungchen.
Das Forum dient zum regen Austausch über Programmierbelange, nicht um Leute dumm zu machen. Bitte respektiere das. Danke.
Ich respektiere das, ohne Kompromisse.
Was ich nicht respektiere, ist der Umstand, dass Hilfestellungen, Vorschläge und gut gemeinte Gedanken hier mit derart frechen Antworten vergütet werden. Wenn du die bisherigen Beiträge des TO liest, fällt dir vielleicht ein gewisser Grundtenor auf.

Jede Geduld genießt das Recht auf ein Ende!
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

Sirius3 hat geschrieben:@Sophus: Was macht Zeile 7 und was Zeile 8? Und wenn Du die Dokumentation gelesen hättest, wüßtest Du, dass Zeile 9 absolut gar nichts macht, weil sie nur etwas abfragt, Dich aber das Ergebnis gar nicht interessiert.
Also bleibt nur Zeile 8 übrig, die was wirkungsvolles tut. Und Du wunderst Dich, dass Deine Toolbar leer ist?
*seufz* Im Grunde schrieb ich es schon, was die Zeile 7 und 8 macht. Aber ich versuche es nochmal:
In Zeile 7 möchte ich der Klasse MDIFormmular die Klasse ToolBarLeiste hinzufügen. Und in Zeile 8 möchte ich mit der Methode addToolBar() eine Werkzeugleiste in der Klasse MDIFormular erstellen.

Nun habe ich Madmartigans Rat befolgt, und das ist erstmal dabei raus gekommen. Ich hoffe, ich bin diesmal richtig vorgegangen.

Code: Alles auswählen

from os import *
import sys  
class MDIFormular(QMainWindow):
    
    def __init__ (self, parent=None): 
        QMainWindow.__init__(self, parent)
        
        [...]
        self.DoShowToolBar = ToolBarLeiste()
        [...]   
             

if __name__ == "__main__":
    print 'Dieses Programm läuft als Main.'
else:
    print 'Das Programm wird von einem anderen Modul importiert.'

# Instanz der MDIFormular
app = QApplication(sys.argv)
MDIWindow = MDIFormular()

# Der Toolbox (Widget) erstellen und einen Parent zuwiesen, um auf 
# dem dem MainWindow angezeigt zu werden.
DoShowToolBar = QToolBar(MDIWindow)

DoShowToolBar.addToolBar("MyToolBar")
MDIWindow.showMaximized()
# Startet die Anwendung und wartet, bis das Fenster geschlossen 
sys.exit(app.exec_())
Aber die Fehlermeldung sieht wie folgt aus:
Traceback (most recent call last):
File "D:\Dan\Python\Xarphus.py", line 3, in <module>
from Xarphus.MDIForm import MDIFormular
File "D:\Dan\Python\Xarphus\MDIForm.py", line 98, in <module>
DoShowToolBar.addToolBar("MyToolBar")
AttributeError: 'QToolBar' object has no attribute 'addToolBar'
Das heißt, irgendwo habe ich bestimmt mal wieder die Methode / Attribut self ausgelassen :-/
BlackJack

`self` ist weder Methode noch Attribut sondern ein Argument das beim Aufruf der Methode übergeben wird. Man könnte statt zu raten was man wo hin schreibt und wo man ein magisches `self` davor schreiben sollte und wo nicht, ja auch mal die GUI-Geschichte für eine kleine Weile beiseite legen, und sich mal grundsätzlich mit OOP auseinander setzen. Aber das wäre wohl zu praktisch gedacht. Dann doch lieber tagelang rätselraten. Macht ja auch Spass. :-)
Sirius3
User
Beiträge: 17745
Registriert: Sonntag 21. Oktober 2012, 17:20

@Sophus: fang endlich mal an die QT-Dokumentation zu lesen. Da gibt es zwei Varianten von addToolBar, die eine ist die, die Du benutzt, die andere ist die, die Du benutzen willst. Wenn Du in Zeile 8 das Attribut von Zeile 7 überschreibst, dann kannst Du Zeile 7 auch gleich weglassen. Das ist das, was Python effektiv macht, aber nicht das, was Du willst. Also folglich ist wohl in Zeile 8 ein Fehler.
Der Code Deines letztes Postings zeigt nur, dass man durch Raten selten ein sinnvolles Programm hinbekommt; dass eine Toolbar keine addToolBar-Methode hat, hatten wir schon vor ein paar Beiträgen.
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

Sirius3 hat geschrieben:@Sophus: fang endlich mal an die QT-Dokumentation zu lesen. Da gibt es zwei Varianten von addToolBar, die eine ist die, die Du benutzt, die andere ist die, die Du benutzen willst. Wenn Du in Zeile 8 das Attribut von Zeile 7 überschreibst, dann kannst Du Zeile 7 auch gleich weglassen. Das ist das, was Python effektiv macht, aber nicht das, was Du willst. Also folglich ist wohl in Zeile 8 ein Fehler.
Der Code Deines letztes Postings zeigt nur, dass man durch Raten selten ein sinnvolles Programm hinbekommt; dass eine Toolbar keine addToolBar-Methode hat, hatten wir schon vor ein paar Beiträgen.
Kannst du mir bitte den Link zu diesem Thema geben? Ich war eben auf der Seite, aber irgendwie wurde ich nicht fündig.
Sirius3
User
Beiträge: 17745
Registriert: Sonntag 21. Oktober 2012, 17:20

Erster link bei einer bekannten Suchmaschine
Antworten