PySide QMdiArea

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
Antworten
ScooB
User
Beiträge: 54
Registriert: Donnerstag 28. April 2011, 10:47

Habe folgendes Problem
Ich habe eine QMidare in der soll noch ein zweites Fenster geöffnet werden
es wird beim Start eins geöffnet allerdings nicht beim Klicken auf den Button in der Toolbar

Code: Alles auswählen

from PySide.QtCore import *
from PySide.QtGui import *
from Start_window import *


class main_window(QMainWindow):
    def __init__(self):
        super(main_window, self).__init__()
        self.resize(1200,900)
        self.move(0,0)
        self.setWindowTitle(' - Schaltanlagenkalkulationstool')
        self.setWindowIcon(QIcon('gfx\icon.png'))
        
        self.mdiArea = QMdiArea()
        self.mdiArea.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        self.mdiArea.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        self.setCentralWidget(self.mdiArea)

        self.windowMapper = QSignalMapper(self)
        self.createToolBars()

    def home_(self):
        homechild=start_window()
        self.mdiArea.addSubWindow(homechild)
        self.mdiArea.activeSubWindow()
        
    def createToolBars(self):
        'EXIT'
        self.exitToolBar = self.addToolBar("Exit")
        self.exit = QAction(QIcon('gfx\exit.png'), 'Exit', self)
        self.connect(self.exit, SIGNAL('triggered()'), SLOT('close()'))      
        self.exitToolBar.addAction(self.exit)
        'EXIT END'
 
        homeToolBar = self.addToolBar('Home')
        home = QAction(QIcon('gfx\new.png'), 'HOME', self)
        homeToolBar.connect(home, SIGNAL("triggered()"), self.home_())
        homeToolBar.addAction(home)

Code: Alles auswählen

import sys, os
from PySide.QtCore import *
from PySide.QtGui import *

class start_window(QDialog):
    def __init__(self, parent=None):
        QDialog.__init__(self, parent)
        
        'Window Anpassung'
        self.resize(1000,800)

        self.setMinimumSize(1000,800)
        self.setMaximumSize(1000,800)
        self.setStyleSheet('background: white')
        self.setWindowTitle('Schaltanlagenkalkulationstool')
        self.setWindowIcon(QIcon('gfx\icon.png'))
        
        self.creategfx()
        self.createbuttons()
        
        label = QLabel(self)
        label.setGeometry(0,150,self.width(), 150)
        label.setFont(QFont('Times',30, QFont.Bold))
        label.setStyleSheet('background: #87CEFA') #0188CC
        label.setText('Kalkulationstool - Schaltanlage')
        label.setAlignment(Qt.AlignHCenter| Qt.AlignCenter)
Zuletzt geändert von Anonymous am Mittwoch 11. Mai 2011, 10:51, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Code-Tags gesetzt.
BlackJack

@ScooB: Dem Fenster wird kein Parent mitgegeben -- das sollte man immer tun, damit auf der Qt-Seite der Speicher korrekt verwaltet werden kann -- und auf der Python-Seite wird nach abarbeiten von `home_()` auch keine Referenz mehr auf das Objekt behalten.

Was soll eigentlich der Unterstrich in `home_()`?

Sonstige Anmerkungen: Klassennamen werden per Konvention in MixedCase geschrieben. Sowohl in Python- als auch in Qt-Programmen. Literale Zeichenketten sollte man nicht als Kommentare missbrauchen. Die haben nur direkt am Anfang eines Moduls, einer Klassendefinition, und Funktionsdefinition eine besondere Bedeutung als Docstring. Dann sollten sie aber auch das entsprechende Objekt beschreiben.

Das "new"-Icon wird wohl so nicht angezeigt werden -- es sei denn da ist tatsächlich ein Zeilenumbruch im Namen.
ScooB
User
Beiträge: 54
Registriert: Donnerstag 28. April 2011, 10:47

@BlackJack: Das mit dem Unterstrich ist nur übergangsweise für mich zu Unterscheidung

ich habe es jetzt geändert auf

Code: Alles auswählen

    def home_(self):
        self.homechild=start_window(self)
        self.mdiArea.addSubWindow(self.homechild)
und

Code: Alles auswählen

class start_window(QDialog):
    def __init__(self,parent):
        QDialog.__init__(self,parent)
aber es tut sich immer noch nichts
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Unterstützt PySide denn die "alte" connect-Syntax überhaupt? Iirc kann es nur die neue...

Code: Alles auswählen

# Dein Code
self.exit = QAction(QIcon('gfx\exit.png'), 'Exit', self)
self.connect(self.exit, SIGNAL('triggered()'), SLOT('close()'))  
# neue Syntax:
self.exit.triggered.connect(close)
Man kann einer QAction aber auch direkt die Funktion übergeben, die bei einem bestimmten Signal aufgerufen werden soll:

Code: Alles auswählen

self.exit = QAction(QIcon(r'gfx\exit.png'), 'Exit', self, triggered=close)
Es sei noch angemerkt, dass Du Raw-Strings benutzen solltest bei Pfaden. Der Backslash escaped bei Dir ja Zeichen... damit sollte def. kein Icon angezeigt werden.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Ok, ich hab mal Deine Snippets zusammengeschustert und lauffähig gemacht:
http://paste.pocoo.org/show/386836/

Du musst bei Widgets auch mal `show()` aufrufen, sonst werden die zwar erstellt, aber nicht angezeigt. Außerdem habe ich ein `print` vor den Aufruf von `activeSubWindow` gesetzt - sonst bringt der einem ja nix ;-)

Die Syntax von connect geht wohl auch im Old-Style Manier; ich finde die neue dennoch schöner. Hier habe ich es wie oben beschrieben direkt gelöst.

DocStrings sollte man imho nicht mitten im Quellcode als Kommentare missbrauchen...

Generell würde ich für das meiste ja auf den QtDesigner zurückgreifen und nur dynamische Sachen von Hand bauen.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
ScooB
User
Beiträge: 54
Registriert: Donnerstag 28. April 2011, 10:47

@Hyperion: Danke jetzt habe ich den Fehler erkannt wieso es bei mir nicht angezeigt wurde
ich hatte es vorher auch schon mit show() allerdings hat es ebenfalls nichts angezeigt und jetzt hab ich es zum Glück erkannt wo mein fehler lag
und zwar bei

Code: Alles auswählen

homeToolBar.connect(home, SIGNAL("triggered()"), self.home_())
bei self.home_ habe ich habe ich die Methode falsch hinzugefügt

naja jetzt erst mal Kopfschmerzen nach der grübelei

Vielen Dank für die Hilfe
ScooB
User
Beiträge: 54
Registriert: Donnerstag 28. April 2011, 10:47

Grad noch ne kleine Frage dazu

wenn ich jetzt sowas habe

Code: Alles auswählen

        languageToolBar = self.addToolBar('Sprachoptionen')
        language = QAction(QIcon(r'gfx/nav/de_flag.jpg'), 'HOME', self, triggered=self.home)
        languageToolBar.addAction(language)
        language = QAction(QIcon(r'gfx/nav/uk_flag.jpg'), 'HOME', self, triggered=self.home)
        languageToolBar.addAction(language)
Kann man bei triggered auch etwas übergeben??

z.B. triggered=self.home(option)

Gruß ScooB
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Stimmt, Du musst natürlich das Funktionsobjekt übergeben und nicht die Funktion aufrufen.
ScooB hat geschrieben: Kann man bei triggered auch etwas übergeben??

z.B. triggered=self.home(option)
Du meinst, ob man `self.home()` noch etwas übergeben kann und nicht `triggered` ;-)

Dazu kann ich Dir einige Links anbieten:
http://www.python-forum.de/viewtopic.ph ... it=partial
http://www.python-forum.de/viewtopic.ph ... it=partial
http://www.python-forum.de/viewtopic.ph ... it=partial

Die Lösung dazu ist `functools.partial`. Damit kannst Du anstelle von `self.home` ein Partial-Objekt erzeugen und mit dem Signal verbinden.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
ScooB
User
Beiträge: 54
Registriert: Donnerstag 28. April 2011, 10:47

@Hyperion: Danke klappt soweit ganz gut aber eine kleine frage wenn ich jetzt eine Variable mitübergeben lasse
dann funktioniert das ganz ja nur veränder ich die Variable dann in der Funktion klappt das ganze auch nur dann kommt das Problem das wenn ich wieder den Button drück das er den wieder den Ursprungswert der Variable nimmt


self.sprachopt wird im Konstruktor initialisiert self.sprachopt=0

Button wird gedrückt

Code: Alles auswählen

language = QAction(QIcon(r'gfx/nav/uk_flag.jpg'), 'English', self, triggered=partial(self.home,1))
Funktion wird ausgeführt

Code: Alles auswählen

    def home(self,sprach_opt):
        homechild=start_window(sprach_opt)
        self.mdiArea.addSubWindow(homechild)
        self.sprachopt = sprach_opt
        homechild.show()
self.sprachopt ist jetzt auf 1

Button wird gedrückt

Code: Alles auswählen

home = QAction(QIcon(r'gfx/nav/home.png'), 'HOME', self, triggered=partial(self.home, self.sprachopt))
self.sprachopt ist komischer weise auf 0
lunar

@ScooB: "foo(bar)" übergibt nicht den Namen "bar" an die Funktion "foo", sondern den Wert, der an diesen Namen gebunden ist. Die Funktion sieht den Namen gar nicht mehr, und bekommt mithin auch überhaupt nicht mit, wenn sich der Wert, der an diesen Namen gebunden ist, ändert.

Arbeite bitte das Tutorial durch, Deine Erwartung offenbart ein fundamentales Missverständnis der Semantik von Python.
Antworten