Neues Fenster verschwindet

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
AlphaX2
User
Beiträge: 53
Registriert: Dienstag 28. Juni 2011, 10:42

Hallo,

na die Frage wird doch durch mein Beispiel erklärt!

Du nutzt mit deiner FirstClass ja ein QMainWindow, dass hat aber quasi "nur" die Aufgabe Leisten, Menüs usw. darzustellen. Aber das MainWindow braucht ein CentralWidget in dem dann die eigentlichen Inhalte eingebaut werden. Darum hab ich ja auch das setCentralWidget(). Im Beispiel is das einfach ein QWidget und in dem QWidget sind dann wieder alle anderen Elemente drinnen, also eine LineEdit, usw. Außerdem empfiehlt es sich eher Layouts zu verwenden, wie das ja in meinem Beispiel auch passiert, statt alles statisch mit move zu setzen. :)
JonnyDamnnox
User
Beiträge: 68
Registriert: Sonntag 10. März 2013, 21:14

Hey AlphaX2, ja schon aber meine Frage war ja wie ich den text vom user mit dem lineEdit rein bekomme, am besten in eine variable so das ich diese das bei QUrl eingeben kann. Also das man die url oben eingibt und dann die Seite geladen wird. Ich hab gelesen das der string auch kein herkömmlicher string ist, sondern ein "QString", ich hab schon 1-2 Sachen dazuh gefunden, leider hat mir nix weiter geholfen :K

Gruß
AlphaX2
User
Beiträge: 53
Registriert: Dienstag 28. Juni 2011, 10:42

Du musst mal überlegen was du bisher eigentlich machst, denn im moment nimmst du im Konstruktor schon den Inhalt des LineEdit auf. Heißt also die Variable wird nie mehr aktualisiert. :) Aber eigentlich sollte ja erst mit dem drücken von Return die Adresse aufgenommen werden. Also so in der Richtung:

Code: Alles auswählen

        # Noch im Konstruktor
        self.lineEdit.returnPressed.connect(self.load_page)

...

    def load_page(self):
        adress = self.lineEdit.text()
        self.webview.load(QtCore.QUrl(adress))
AlphaX2
JonnyDamnnox
User
Beiträge: 68
Registriert: Sonntag 10. März 2013, 21:14

Hm ok danke, so ähnlich hatte ich das auch vor, im konstruktor klappts natürlich. Aber würdest du Vorschlagen das ich startingUi + lineEditect komplett in __init__ verlege? Also startingUi weg und nur noch __init__ (vorerst) ?

Gruß
AlphaX2
User
Beiträge: 53
Registriert: Dienstag 28. Juni 2011, 10:42

Naja kann man machen, muss man nicht. Gehen sollte beides, an und für sich werden gerne die Menüs und die Actions in eine Methode verlagert. Die absoluten Hauptelemente könnte man auch direkt im __init__ lassen.

AlphaX2
JonnyDamnnox
User
Beiträge: 68
Registriert: Sonntag 10. März 2013, 21:14

Ok, mal gucken^^ Allerdings muss das lineEdit ect. nicht im konstruktor sein, funktioniert auch wenn es in der startingUi ist. Es ist wahrscheinlich weil "adress" jetzt in einer eigenen Funktion ist, ganz verstanden hab ich das ganze aber nicht wirklich :/

Gruß
AlphaX2
User
Beiträge: 53
Registriert: Dienstag 28. Juni 2011, 10:42

Sagte ich ja, beides dürfte gehen! :)

Zum Verstehen: Du musst dir mal die zeitliche Abfolge überlegen; in deiner main() bildest du eine Instanz von FirstClass, dann wird durch die __init__ (welche ja quasi wie ein Bauplan ist) dein Objekt, hier also ein QMainWindow "gebaut". Und steht dann bereit. Wenn du da schon mit lineEdit.text() die Eingabe an eine Variable bindest, dann wird die doch SOFORT beim erstellen abgefragt und die Variable hält dann eben die leere Zeile (denn am Anfang steht ja nix drinnen).

Wenn du aber den Enter-Button (returnPressed) mit einer Funktion (self.load_page) verbindest, dann wird ja load_page(self) erst aufgerufen, wenn du auch Enter gedrückt hast. Also vielleicht Minuten oder Stunden nachdem du das QMainWindow als Referenz erzeugt hast. Und wenn dann eben was in der lineEdit steht, wird das ja auch erst in dem Moment abgerufen und als zu ladender Link übergeben. Zumal das eben auch mit jedem Enter-drücken wieder neu aufgerufen wird und damit immer neu abgefragt wird. :)

Hoffe das war jetzt verständlich. Sonst frag ruhig, bzw. lies nochmal bisl rum was ein Konstruktor ist, wie Klassen funktionieren und was das Signal-Slot bei Qt ist. ;)

AlphaX2
JonnyDamnnox
User
Beiträge: 68
Registriert: Sonntag 10. März 2013, 21:14

hi, also ich hab jetzt alles angewendet was mir hier gesagt wurde:

Code: Alles auswählen

import sys
from PySide import QtGui, QtCore, QtWebKit


class FirstClass(QtGui.QMainWindow):

    def __init__(self):
        super(FirstClass, self).__init__()
        self.startingUI()


    def startingUI(self):

        self.setWindowTitle('Hauptfenster')
        self.resize(800, 600)
        self.statusBar()
        menue = self.menuBar()
        self.statusBar()

        menuleiste_datei = menue.addMenu('File')

        datei_exit = QtGui.QAction('Exit', self)
        datei_exit.setStatusTip('Close the programm')
        menuleiste_datei.addAction(datei_exit)
        datei_exit.triggered.connect(self.close)

        #Einstellungen menue
        menuleiste_configurations = menue.addMenu('Configurations')
        configurations_settings = QtGui.QAction('Settings', self)
        configurations_settings.setStatusTip('Configurations(Settings)')
        menuleiste_configurations.addAction(configurations_settings)
        configurations_settings.triggered.connect(self.newwindow)

        self.mainWidget = QtGui.QWidget(parent=self)
        self.setCentralWidget(self.mainWidget)
        self.url_eingabe = QtGui.QLineEdit()
        self.url_eingabe.returnPressed.connect(self.load_page)
        self.webview = QtWebKit.QWebView(self)

        self.layout = QtGui.QVBoxLayout()
        self.layout.addWidget(self.url_eingabe)
        self.layout.addWidget(self.webview)
        self.layout.addStretch(1)

        self.mainWidget.setLayout(self.layout)
        self.show()

    def newwindow(self):
        self.wid = QtGui.QWidget()
        self.wid.resize(250, 150)
        self.setWindowTitle('NewWindow')
        self.wid.show()

    def load_page(self):
        self.adress = self.url_eingabe.text()
        self.webview.load(QtCore.QUrl(self.adress))



def main():

    app = QtGui.QApplication(sys.argv)
    start = FirstClass()
    sys.exit(app.exec_())

if __name__== '__main__':
    main()

Es funktioniert auch sehr schön. Es wird aber empfohlen das man die Attribute in __init__ stopft. Wenn ich das mache ( also : self.adress = self.url_eingabe.text(), unter initUi ) Dann wird keine url mehr geladen. :K Ich könnte mir das erklären damit das eben in __init__ erst das ganze Zeug geladen wird, dann aber eben der url_eingabe.text() fehlt, den man ja für einen "Zwischenschritt" braucht. Wie löse ich das jetzt? Und das mit den Klassen und Vererbung hab ich schon verstanden. Nur leider weiß ich nicht wieso man da ein parent=self einsetzt und wann ich self benutzen muss und wann nicht.

Gruß
BlackJack

@JonnyDamnnox: Man sollte in der `__init__()` oder zumindest nach dem diese ausgeführt wurde, alle Attrbute auf der Klasse definiert haben. Und nicht in anderen Methoden später neue hinzufügen. Das heisst ja nicht, dass man die nicht *ändern* darf. Setze `self.address` auf den Inhalt den Du am Anfang in der Adresszeile haben möchtest, und dann den Inhalt von dem `self.url_eingabe`-Widget auf diesen Wert. Den Rest der mit diesem Widget zu tun hat, kannst Du so lassen.

Das erste Argument einer Methode ist das Objekt auf dem diese Methode aufgerufen wird. Per Konvention nennt man diesen Parameter `self`. Diesen Namen muss man also immer dann benutzen, wenn man auf ein Attribut — Datum oder Methode — auf diesem Objekt zugreifen möchte. Und man benutzt es nicht wenn man nicht auf das Objekt zugreifen möchte. Insbesondere bindet man keine lokalen Namen unnötig an das Objekt, oder irgend welche Werte die nicht zum Zustand des Objekts gehören.
JonnyDamnnox
User
Beiträge: 68
Registriert: Sonntag 10. März 2013, 21:14

Hallo, also ok, um diese Sachen kümmere ich mich dann als letztes :D, trotzdem danke für die Antwort darauf :-)

Da der normale rudimentäre Browser jetzt einigermaßen läuft, will das ich das ganze jetzt mit QGraphics machen, damit ich später mehr mit der Grafik machen kann. Leider(natürlich), gibt es wieder Probleme:

Code: Alles auswählen

import sys
from PySide import QtGui, QtCore


class FirstClass(QtGui.QMainWindow):


    def __init__(self):
        super(FirstClass, self).__init__()
        self.startingUI()


    def startingUI(self):

        self.setWindowTitle('Hauptfenster')
        self.resize(800, 600)
        menu = self.menuBar()
        self.statusBar()
        menuleiste_datei = menu.addMenu('File')

        self.mainWidget = QtGui.QGraphicsWidget()

        self.scene = QtGui.QGraphicsScene(self)

        self.lineedit = QtGui.QLineEdit()
        self.textedit = self.scene.addWidget(self.lineedit)


        self.layout = QtGui.QGraphicsLinearLayout()
        self.layout.addItem(self.textedit)
        self.layout.addStretch(1)

        self.form = QtGui.QGraphicsWidget()
        self.form.setLayout(self.layout)
        self.scene.addItem(self.form)


        self.view = QtGui.QGraphicsView(self.scene)
        self.setCentralWidget(self.view)


        self.view.show()
        self.show()


def main():

    app = QtGui.QApplication(sys.argv)
    start = FirstClass()
    sys.exit(app.exec_())

if __name__== '__main__':
    main()
Das Fenster sieht so schon ganz hübsch aus :D Ich hab versucht das analog wie beim alten code zu machen. Es gibt einige Sachen die ich nicht verstanden hab, zB self.setCentralWidget(self.view). Das mit add strech geht auch nicht(also das ich lineEdit unter das Menü kriege, so wie bei dem anderen "browser"). Kann ich überhaupt einfach QMainWindow mit QGraphics verbinden, oder gibt es für QGraphics ein eigenes analoges QMainWindow(oder ist das etwa QtGraphicsScene? Obwohl in der doc steht das bei QMainWindow jedes widget benutzt werden kann, bin aber nicht sicher). Wenn ich das Programm mit klick auf x oben rechts machen kommt auch ein Fenster mit "python.exe wurde beendet blabla", woher zum Geier kommt das???


Gruß
Antworten