Einen Moment, ich schaue mal nach.BlackJack hat geschrieben:@Sophus: Wenn ich das Starte und auf Film hinzufügen gehe, dann passiert nichts, und in der Konsole wird mir das hier ausgegeben:Also genau das Problem das ich auch beim verkürzten Programm hatte.Code: Alles auswählen
$ python Xarphus.py Die Ordner existieren bereits. Das Programm wird von einem anderen Modul importiert. Traceback (most recent call last): File "/home/bj/tmp/forum/Xarphus/Xarphus/MDIForm.py", line 100, in CreateNewMovie self.MDIChild = start_window(self) NameError: global name 'start_window' is not defined
Fenster mit QHBoxLayout schließen
In der MDIForm.py Datei folgendes ändern:
Code: Alles auswählen
def CreateNewMovie(self): # Neues Fenster für Film hinzufügen öffnen
self.MDIChild = MyForm(self) #<---- ansttt start_window kommt hier MyForm hin.
self.mdiArea.addSubWindow(self.MDIChild)
self.MDIChild.show()
print "Dialog lädt"
Hab dir mal ein Beispiel gebastelt, damit du siehst, das Internationalisierung kein Hexenwerk ist und schon sehr bequem umgesetzt werden kann:
https://github.com/Cermit/snippets/tree ... 8n_example
Vorgehen:
Du erzeugst deinen Quelltext (hier main.py). Alle Strings, die übersetzt werden sollen, setzt du in self.tr().
Du legst ein pro-File (hier project.pro) an, in dem die Dateien aufgeführt werden, in denen Strings zur Übersetzung vorgesehen sind.
Du benutzt das CLI-Tool bzw (je nach verwendeter PyQt-Version) um die ts-Files zu erzeugen (sind nichts anderes als xml-Files).
Du benutzt den Qt Linguist, um die Übersetzungen anzugeben und gibst zum Schluss dort mit "Freigeben" die Datei frei. Dann wird ein qm-File erzeugt, das vom QTranslator zur Laufzeit des Programms eingelesen werden kann.
Es sind halt im wesentlichen drei Zeilen mehr:
die du benötigst. Das kannst du natürlich jetzt noch beliebig erweitern, d.h. beim Programmstart aus deinen Settings die Sprachwahl auslesen und dementsprechend das richtige qm-File auswählen. Das ist aber bei weitem einfacher als das, was du vorhast und ich sehe hierbei auch keinen wirklichen Lerneffekt.
https://github.com/Cermit/snippets/tree ... 8n_example
Vorgehen:
Du erzeugst deinen Quelltext (hier main.py). Alle Strings, die übersetzt werden sollen, setzt du in self.tr().
Du legst ein pro-File (hier project.pro) an, in dem die Dateien aufgeführt werden, in denen Strings zur Übersetzung vorgesehen sind.
Du benutzt das CLI-Tool
Code: Alles auswählen
pylupdate5 project.pro
Code: Alles auswählen
pylupdate4 project.pro
Du benutzt den Qt Linguist, um die Übersetzungen anzugeben und gibst zum Schluss dort mit "Freigeben" die Datei frei. Dann wird ein qm-File erzeugt, das vom QTranslator zur Laufzeit des Programms eingelesen werden kann.
Es sind halt im wesentlichen drei Zeilen mehr:
Code: Alles auswählen
[...]
translator = QtCore.QTranslator()
translator.load('de.qm')
app.installTranslator(translator)
[...]
Hallo EmaNymton,EmaNymton hat geschrieben:Hab dir mal ein Beispiel gebastelt, damit du siehst, das Internationalisierung kein Hexenwerk ist und schon sehr bequem umgesetzt werden kann:
https://github.com/Cermit/snippets/tree ... 8n_example
Vorgehen:
Du erzeugst deinen Quelltext (hier main.py). Alle Strings, die übersetzt werden sollen, setzt du in self.tr().
Du legst ein pro-File (hier project.pro) an, in dem die Dateien aufgeführt werden, in denen Strings zur Übersetzung vorgesehen sind.
Du benutzt das CLI-ToolbzwCode: Alles auswählen
pylupdate5 project.pro
(je nach verwendeter PyQt-Version) um die ts-Files zu erzeugen (sind nichts anderes als xml-Files).Code: Alles auswählen
pylupdate4 project.pro
Du benutzt den Qt Linguist, um die Übersetzungen anzugeben und gibst zum Schluss dort mit "Freigeben" die Datei frei. Dann wird ein qm-File erzeugt, das vom QTranslator zur Laufzeit des Programms eingelesen werden kann.
Es sind halt im wesentlichen drei Zeilen mehr:die du benötigst. Das kannst du natürlich jetzt noch beliebig erweitern, d.h. beim Programmstart aus deinen Settings die Sprachwahl auslesen und dementsprechend das richtige qm-File auswählen. Das ist aber bei weitem einfacher als das, was du vorhast und ich sehe hierbei auch keinen wirklichen Lerneffekt.Code: Alles auswählen
[...] translator = QtCore.QTranslator() translator.load('de.qm') app.installTranslator(translator) [...]
besten Dank für deine kleine Demonstration. Aber eine Frage: Wie kann ich dein kleines Beispiel herunterladen? Muss ich mich erst auf der Seite anmelden? Und dann hätte ich eines anzumerken. Wenn ich mir das alles so durchlese, was ich machen muss, dann schlage ich mir die Hände über meinem Kopf zusammen. Da sind ja ganze 4-5 Schritte die ich machen muss, bis ich am Ende erstmal eine *.qm Datei habe. In meinem Vorgang habe ich Sprachmodule, muss nicht erst 5 Schritte durchlaufen, bis ich am Ende eine *.qm Datei habe. Ich würde mir gern dein Code ansehen, aber überzeugt von den ganzen umständlichen Schritten bin ich immer noch nicht. Da habe ich in meinem Vorgang nur einen einzigen Schritt.
@Sophus: Das mit den Qt-Linguist unterscheidet sich von deinem Ansatz. Das ist nämlich für den Programmierer und für den Übersetzer einfacher. Aber mach's ruhig kompliziert wenn Du unbedingt willst.
Hallo BlackJack, konntest du mein kleines Projekt zum Laufen bringen und kannst du mir bezüglich meines Ausgangsproblem helfen?BlackJack hat geschrieben:@Sophus: Das mit den Qt-Linguist unterscheidet sich von deinem Ansatz. Das ist nämlich für den Programmierer und für den Übersetzer einfacher. Aber mach's ruhig kompliziert wenn Du unbedingt willst.
@Sophus: Da hatte ich doch schon etwas zu geschrieben: `QDialog` ist ein „top-level only”-Widget. Das kann man nur als eigenes Fenster verwenden und nicht als Widget in andere Widgets einbauen.
Ach so, das heißt konkret für mich, dass ich aus QDialog nun QWidget machen muss, richtig? Aber selbst dann schließt sich das Programm leider nicht, sondern die Widgets auf der Form verschwinden.BlackJack hat geschrieben:@Sophus: Da hatte ich doch schon etwas zu geschrieben: `QDialog` ist ein „top-level only”-Widget. Das kann man nur als eigenes Fenster verwenden und nicht als Widget in andere Widgets einbauen.
Selbst 'destroy()' will auch nicht ganz funktionieren. Wie gesagt, ich habe aus QDialog nun QWidget gemacht, in der Hoffnung, dass man mit einem QWidget in einem MdiArea-Widget arbeiten kann. Aber irgendwie scheint es nicht ganz zu funktionieren. Woran könnte es denn liegen?
@Sophus: Kommando zurück. Anscheinend funktioniert es auch mit `QDialog`-Exemplaren. Allerdings muss man schon das richtige Objekt schliessen. Nämlich das `QMdiSubWindow`-Exemplar das zu dem `QMdiArea`-Exemplar hinzugefügt wird. Wenn man nur das Widget zerstört welches *in* diesem `QMdiSubWindow`-Exemplar angezeigt wird, dann wird halt auch nur der Inhalt von dem Fenster zerstört.
Wobei: Kommando zurück wieder zurück: Auch wenn `QDialog` funktioniert, würde ich das nur verwenden wenn man tatsächlich irgend etwas von diesem speziellen Widget verwendet. Wenn ein `QWidget`-Exemplar reicht, muss man es ja nicht unnötig kompliziert machen.
Wobei: Kommando zurück wieder zurück: Auch wenn `QDialog` funktioniert, würde ich das nur verwenden wenn man tatsächlich irgend etwas von diesem speziellen Widget verwendet. Wenn ein `QWidget`-Exemplar reicht, muss man es ja nicht unnötig kompliziert machen.
Hey BlackJack, das Problem, was ich hier habe, ist, dass ich keinen Unterschied zwischen QWidget und QDialog verstehe. Da ich VB6ler bin, gibt es dort nur Formen, und die Formen kann man behandeln wie man will. Und ich habe die Formen auch in ein MDIFormular (Analog: QMdiArea) untergebracht, indem die Formen als Child behandelt wurden.BlackJack hat geschrieben:@Sophus: Kommando zurück. Anscheinend funktioniert es auch mit `QDialog`-Exemplaren. Allerdings muss man schon das richtige Objekt schliessen. Nämlich das `QMdiSubWindow`-Exemplar das zu dem `QMdiArea`-Exemplar hinzugefügt wird. Wenn man nur das Widget zerstört welches *in* diesem `QMdiSubWindow`-Exemplar angezeigt wird, dann wird halt auch nur der Inhalt von dem Fenster zerstört.
Wobei: Kommando zurück wieder zurück: Auch wenn `QDialog` funktioniert, würde ich das nur verwenden wenn man tatsächlich irgend etwas von diesem speziellen Widget verwendet. Wenn ein `QWidget`-Exemplar reicht, muss man es ja nicht unnötig kompliziert machen.
Aber nun zum Problem:
Du sagtest, ich solle das Objekt 'QMdiSubWindow' schließen, richtig? Jedoch habe ich dieses Objekt ja gar nicht. Schauen wir mal meine Funktion an:
Code: Alles auswählen
def CreateNewMovie(self): # Neues Fenster für Film hinzufügen öffnen
self.MDIChild = MyForm(self)
self.mdiArea.addSubWindow(self.MDIChild)
self.MDIChild.show()
print "Dialog lädt"
@Sophus: `MDIChild` wird nicht als Subwindow hinzugefügt, sondern dem Subwindow als Inhalt. Schau Dir mal die Dokumentation zu `QMdiArea.addSubWindow()` an. Danach solltest Du zwei Wege kennen um an das `QMdiSubWindow`-Exemplar heran zu kommen.
Nach langem rumgetüffel bin ich auf eine vermeintliche Lösung gestoßen, aber ich hätte gern eure Meinung.
TestDialog.py Was tat ich? Ich habe die Klasse "MyForm" unter anderem von QMdiSubWindow abgeleitet, schließlich sollten alle Child-Fenster bei QMdiArea von QMdiSubWindow abgeleitet werden. Vorher war sie nur vom QDialog und zeitweise auch nur vom QWidget abgeleitet. Klappte ja nicht.
MDIForm.py Hier schließe ich das Fenster mit der Methode 'removeSubWindow()', aber mit 'close()' klappt es auch wunderbar. Kann ich also getrost bei 'close()' bleiben oder sollte ich da auf etwas achten?
TestDialog.py Was tat ich? Ich habe die Klasse "MyForm" unter anderem von QMdiSubWindow abgeleitet, schließlich sollten alle Child-Fenster bei QMdiArea von QMdiSubWindow abgeleitet werden. Vorher war sie nur vom QDialog und zeitweise auch nur vom QWidget abgeleitet. Klappte ja nicht.
Code: Alles auswählen
import sys
from PyQt4.QtGui import QWidget, QApplication, QVBoxLayout, QHBoxLayout, QLabel, QLineEdit, QPushButton, QMessageBox, QTextEdit, QMdiSubWindow
from PyQt4.QtCore import Qt
class MyForm(QMdiSubWindow, QDialog):
def __init__(self, parent=None):
QMdiSubWindow, QDialog.__init__(self, parent)
[...]
Code: Alles auswählen
[...]
def CloseQWidget(self):
self.MDIChild = MyForm(self)
self.mdiArea.removeSubWindow(self.MDIChild)
#self.close()
[...]
@Sophus: Das ist kompletter Unsinn. Wieder Programmieren durch raten statt zu verstehen was man da tut. Und bei beiden gezeigten Programmstellen hätte ich gewettet damit fällt man auf die Nase. Wenn das tatsächlich funktioniert, fällt das wohl unter die Kategorie „feak accident”. Oder Du trollst hier gerade ganz gewaltig.
Edit: Und es funkioniert auch tatsächlich *nicht*. Das Layout in dem MDI-Fenster ist kaputt und auf der Konsole erscheint auch eine entsprechende Warnung von Qt:
Wie die Schaltfläche vom `MyForm`-Objekt mit der gezeigten `CloseQWidget()`-Methode verbunden wird, will ich wahrscheinlich gar nicht wissen. Unsinnig ist sie allemal, sowohl der aktive Code als auch die auskommentierte Zeile.
Edit: Und es funkioniert auch tatsächlich *nicht*. Das Layout in dem MDI-Fenster ist kaputt und auf der Konsole erscheint auch eine entsprechende Warnung von Qt:
Code: Alles auswählen
QLayout: Attempting to add QLayout "" to MyForm "", which already has a layout
QWidget::setLayout: Attempting to set QLayout "" on MyForm "", which already has a layout
@Sophus: was glaubst Du, bewirkt die Zeile
Wahrscheinlich: auf wundersame Weise wird das Verhalten von QMdiSubWindow und QDialog miteinander vermischt, so dass ein QMdiSubDialog entsteht, der alles genau so macht, wie ich mir das wünsche.
In Wirklichkeit macht Python ein Tuple aus dem Objekt QMdiSubWindow und dem Rückgabewert von QDialog.__init__ und verwirft es gleich wieder.
Hättest Du einmal in die Dokumentation geschaut:
wäre klar, woher das QMdiSubWindow kommt und dass Du ein QWidget statt eines QDialogs brauchst.
Code: Alles auswählen
QMdiSubWindow, QDialog.__init__(self, parent)
In Wirklichkeit macht Python ein Tuple aus dem Objekt QMdiSubWindow und dem Rückgabewert von QDialog.__init__ und verwirft es gleich wieder.
Hättest Du einmal in die Dokumentation geschaut:
Code: Alles auswählen
QMdiSubWindow addSubWindow(self, QWidget widget, Qt.WindowFlags flags=0)
Bei mir kommt keine Warnung. Hier die verpackte Datei, damit ihr mein komplettes Projekt ansehen könnt': Xarphus.
Werter BlackJack, du kannst ein paar Gänge runterschalten. Mir zu unterstellen ich trolle oder gar mich von der Seite anzufahren empfinde ich mehr als dreist und unhöflich. Das ich als Anfänger nicht gleich alles auf Anhieb verstehe und richtig mache, sollte einem jeden klar sein. Sollte dein Geduldsfaden sehr kurz sein, hoffe ich wirklich, dass du kein Ausbilder bist. Und bevor du wieder denkst, dass ich trolle, kommen wir wieder zurück. Ja, ich habe die Qt Dokumentation gelesen, aber ich muss gestehen, dass ich mich immer noch irgendwie schwer tue an die Seite heranzukommen. Es liegt weniger daran, dass die Seite auf englisch ist, sondern wie die Seite aufgebaut ist. Es stehen so viele Informationen, dass der Scrollbalken im Browser richtig klein wird. Aber irgendwie habe ich das richtige Lesen noch nicht erfasst. Und anstatt mich hier als Troll abzustempeln könnte man mir zeigen, wie man auf der Seite richtig liest, wie man vorzugehen hat, wie man Informationen herausnimmt etc.
Werter BlackJack, du kannst ein paar Gänge runterschalten. Mir zu unterstellen ich trolle oder gar mich von der Seite anzufahren empfinde ich mehr als dreist und unhöflich. Das ich als Anfänger nicht gleich alles auf Anhieb verstehe und richtig mache, sollte einem jeden klar sein. Sollte dein Geduldsfaden sehr kurz sein, hoffe ich wirklich, dass du kein Ausbilder bist. Und bevor du wieder denkst, dass ich trolle, kommen wir wieder zurück. Ja, ich habe die Qt Dokumentation gelesen, aber ich muss gestehen, dass ich mich immer noch irgendwie schwer tue an die Seite heranzukommen. Es liegt weniger daran, dass die Seite auf englisch ist, sondern wie die Seite aufgebaut ist. Es stehen so viele Informationen, dass der Scrollbalken im Browser richtig klein wird. Aber irgendwie habe ich das richtige Lesen noch nicht erfasst. Und anstatt mich hier als Troll abzustempeln könnte man mir zeigen, wie man auf der Seite richtig liest, wie man vorzugehen hat, wie man Informationen herausnimmt etc.
Zuletzt geändert von Sophus am Samstag 21. Juni 2014, 15:21, insgesamt 2-mal geändert.
Hallo Sirius3,Sirius3 hat geschrieben: Wahrscheinlich: auf wundersame Weise wird das Verhalten von QMdiSubWindow und QDialog miteinander vermischt, so dass ein QMdiSubDialog entsteht, der alles genau so macht, wie ich mir das wünsche.
In Wirklichkeit macht Python ein Tuple aus dem Objekt QMdiSubWindow und dem Rückgabewert von QDialog.__init__ und verwirft es gleich wieder.
Hättest Du einmal in die Dokumentation geschaut:wäre klar, woher das QMdiSubWindow kommt und dass Du ein QWidget statt eines QDialogs brauchst.Code: Alles auswählen
QMdiSubWindow addSubWindow(self, QWidget widget, Qt.WindowFlags flags=0)
an dieser Stelle bin ich in der Dokumentation auch angekommen. Aber ehrlich gesagt sagt mir dieser Ausschnitt nicht viel. Gut, wir brauchen statt einen QDialog ein QWidget? Super, dann werde ich folgendes machen:
TestDiaolog.py
Code: Alles auswählen
# -*- coding: utf-8 -*-
import sys
from PyQt4.QtGui import QWidget, QApplication, QVBoxLayout, QHBoxLayout, QLabel, QLineEdit, QPushButton, QMessageBox, QTextEdit, QMdiSubWindow, QDialog
from PyQt4.QtCore import Qt
class MyForm(QWidget):
def __init__(self, parent=None):
QWidget.__init__(self, parent)
[...]
Code: Alles auswählen
[...]
def CreateNewMovie(self): # Neues Fenster für Film hinzufügen öffnen
self.MDIChild = MyForm(self)
self.mdiArea.addSubWindow(self.MDIChild)
self.MDIChild.show()
print "Dialog lädt"
def CloseQWidget(self):
self.MDIChild = MyForm(self)
#self.mdiArea.closeAllSubWindows()
#self.mdiArea.removeSubWindow(self.MDIChild)
self.close()
[...]
@Sophus: Weil Du sowieso nicht aufgibt, bis man es Dir vorkaut:
Code: Alles auswählen
[...]
def CreateNewMovie(self): # Neues Fenster für Film hinzufügen öffnen
self.form = MyForm(self)
self.subwindow = self.mdiArea.addSubWindow(self.form)
self.form.show()
def CloseQWidget(self):
self.subwindow.close()
[...]
@Sirius3: Wobei man sich dann natürlich fragt wie/womit `CloseQWidget()` verknüpft wird, und das *ein* Attribut für das Fenster für MDI-Fenster, von denen man ja durchaus mehr als eins erzeugen kann, nicht funktionieren wird. Die `CloseQWidget()`-Methode schliesst dann immer nur das zuletzt geöffnete. Sophus hat sich hier einfach hoffnungslos übernommen und kommt da auch nicht raus ohne sich endlich mal mit OOP, und den Grundlagen von Qt zu beschäftigen.