Die engstirnige MessageBox

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 Leute,

ist es irgendwie möglich die QMessageBox nach eigenem Belieben zu manipulieren? Nun standardmäßig arbeitet man ja wie folgt mit der QMessageBox:

Code: Alles auswählen

reply = QtGui.QMessageBox.information(self, "Delete Picture", "Delete these " + str(count) + " selected pictures from the album '" + str(album) + "'?",
                                      QtGui.QMessageBox.Yes, QtGui.QMessageBox.No)
Hier kann man den Titel und den Text der QMessageBox beliebig bearbeiten, aber hier die Yes- und No-Buttons leider nicht. Bei mir werden sie auf Englisch ausgegeben. Dort steht tatsächlich Yes und No. Und wie sieht es aus, wenn der Text in der MessageBox auf deutsch ist, und die Buttons inkonsequenterweise auf englisch sind? Gibt es eine Möglichkeit an die Buttons der QMessageBox heranzukommen? Nicht dass man dabei tief in die API-Kiste greifen muss. Nun, in VB6 ist es absolut kein Problem.
BlackJack

@Sophus: Schon versucht die Sprache der Anwendung auf Deutsch umzuschalten?
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

Sprache der Anwendung? Welche Anwendung?
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

@Sophus: Qt hat in Internationalisierungsmodul integriert. Damit kann man alle Texte in seinem Programm für verschiedene Sprachen anpassen. Für die Standard-Dialoge gibt es bereits Übersetzungen.
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

Sirius3 hat geschrieben:@Sophus: Qt hat in Internationalisierungsmodul integriert. Damit kann man alle Texte in seinem Programm für verschiedene Sprachen anpassen. Für die Standard-Dialoge gibt es bereits Übersetzungen.
Du meinst mit der 'tr("")'-Methode?
BlackJack

@Sophus: Ja, die wird intern dafür verwendet, aber Du musst nur die Sprache für die Anwendung setzen. Kleiner Tipp, Anwendung heisst auf englisch „Application”.
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

BlackJack hat geschrieben:@Sophus: Ja, die wird intern dafür verwendet, aber Du musst nur die Sprache für die Anwendung setzen. Kleiner Tipp, Anwendung heisst auf englisch „Application”.
Danke für die kleine English-Stunde, BlackJack :-) Aber bei meinem Verfahren (du erinnerst dich, ich arbeite mit den Dictionaries - German.py und English.py) wäre es nicht möglich die QMessageBox zu manipulieren? Und wenn wir bei der 'tr("")'-Methode bleiben, so muss ja erstmal ein Text drinstehen, welche als String ausgelesen werden kann. Und im Falle der QMessageBox wüsste ich nicht, wo ich die 'tr("")'-Methode anwenden soll. Wie ich bereits am Anfang des Threads gezeigt habe, wurden zunächst einmal zwei Buttons angegeben, einmal '.Yes' und einmal '.No'. Wo aber kann ich die Buttons nun sowohl in meinem Verfahren als auch mit der 'tr("")'-Methode beschriften?
BlackJack

@Sophus: „Du musst nur die Sprache für die Anwendung setzen.”
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

BlackJack hat geschrieben:@Sophus: „Du musst nur die Sprache für die Anwendung setzen.”
Das Problem liegt aber eher darin, dass der Anwender gerne eine Sprache wählen möchte. Und in meiner Variante würde er sich eine Sprache, angenomen German, auswählen, mein Programm schreibt die Auswahl in eine INI-Datei, und wendet die Sprache im Anschluss an, indem dann das Modul "German.py" importiert wird. Und nun nochmal die Frage: Wie? Ich glaube wir reden aneinander vorbei.
BlackJack

@Sophus: Also ich rede von den Beschriftungen von den Schaltflächen die von Qt gesetzt werden. Weil das Deine Frage war, wenn ich den Ausgangsbeitrag richtig verstanden habe. Wenn Du da eine andere Sprache haben willst, dann musst Du eine Sprache auf der Anwendung setzten. Welche Sprache und wie die ausgewählt wurde, vom Benutzer, per Zufall, nach Mondphase, …, ist davon völlig unabhängig.

Wie das bei Qt gehandhabt wird, steht in der Dokumentation.
EmaNymton
User
Beiträge: 174
Registriert: Sonntag 30. Mai 2010, 14:07

Ich hatte ja in dem anderen Thread schon bereits auf den QTranslator hingewiesen, was dir ja aber zu kompliziert war. Hier würde er dir wieder viel Arbeit abnehmen, da die Jungs von Qt schon die qm-Files für Standardbeschriftungen mitliefern und du sie nur noch einbinden musst.
Du kannst aber natürlich auch den Text manuell setzen. Das ergibt aber imho nur dann Sinn, wenn man nicht auf die Standardbeschriftung zurückgreifen will, sondern etwas eigenes braucht/möchte. Wie man das macht, findet man in der Dokumentation von QMessageBox. Ich habe mir mal ein Minimalbeispiel gebastelt, dass einen einfachen Anwendungsfall zeigt, bitte die Frage/Anworten nicht so ernst nehmen, SCNR ;)

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
from PyQt4 import QtGui, QtCore

class Minimalbeispiel(QtGui.QWidget):
    def __init__(self):
        QtGui.QWidget.__init__(self)  
        self.layout = QtGui.QHBoxLayout(self)
        self.pushButton_1 = QtGui.QPushButton(self.tr(u"Drück mich!"), self)
        self.pushButton_2 = QtGui.QPushButton(self.tr(u"Mich auch!"), self)
        self.dialog_text = u"Will ich die Dokumentation von Qt lesen?"
        self.layout.addWidget(self.pushButton_1)
        self.layout.addWidget(self.pushButton_2)
        
        self.pushButton_1.clicked.connect(self.button_clicked_1)
        self.pushButton_2.clicked.connect(self.button_clicked_2)
        self.show()

    def button_clicked_1(self):
        message_box = QtGui.QMessageBox()
        message_box.setStandardButtons(QtGui.QMessageBox.Yes | 
                                       QtGui.QMessageBox.No)
        message_box.setText(self.dialog_text)
        message_box.button(QtGui.QMessageBox.Yes).setText(
                                           self.tr(u"Ja, mache ich!"))
        message_box.button(QtGui.QMessageBox.No).setText(
                                           self.tr(u"Nein, nie und nimmer!"))
        reply = message_box.exec_()
        self.evaluate_reply(reply)

    def button_clicked_2(self):
        reply = QtGui.QMessageBox.information(self, u"Frage", self.dialog_text,
                                  QtGui.QMessageBox.Yes, QtGui.QMessageBox.No)
        self.evaluate_reply(reply)

    def evaluate_reply(self, reply):
        if reply == QtGui.QMessageBox.Yes:
            print "Super, alles wird gut!"
        else:
            print "Das wäre aber besser! ;)"


if __name__=="__main__":
    app = QtGui.QApplication(sys.argv)
    translator = QtCore.QTranslator()
    translator.load("".join(["qt_",str(QtCore.QLocale().system().name())]), 
           QtCore.QLibraryInfo.location(QtCore.QLibraryInfo.TranslationsPath))
    app.installTranslator(translator)
    fenster = Minimalbeispiel()
    sys.exit(app.exec_())
BlackJack

@EmaNymton: Das Erstellen des Namens der Übersetzung für `QTranslator.load()` sieht unnötig umständlich aus. Zwei gegebene Zeichenketten mit ``''.join()`` zu verbinden ist umständlicher ausgedrückt als einfach ``+``. Das `str()` sollte nicht nötig sein. Und man muss kein `QLocale`-Exemplar erstellen, denn `system()` ist eine statische Methode.

Code: Alles auswählen

In [8]: ''.join(['qt_', str(QtCore.QLocale().system().name())])
Out[8]: 'qt_en_GB'

In [9]: 'qt_' + QtCore.QLocale.system().name()
Out[9]: PyQt4.QtCore.QString(u'qt_en_GB')

In [10]: _8 == _9
Out[10]: True
Das das Ergebnis einen anderen Typ hat ist nicht so wichtig, denn einen `QString` kann man der Methode natürlich auch übergeben.
EmaNymton
User
Beiträge: 174
Registriert: Sonntag 30. Mai 2010, 14:07

@BlackJack: Da hast du Recht, keine Ahnung was mich da geritten hat. ;) Bzw. ich hab doch ne Ahnung, ich meine, dass u.a. auch hier im Forum immer wieder geschrieben wird, dass man Zeichenketten gerade nicht mit + verknüpfen soll, u.a. aus Performance-Gründen, was hier ja aber nicht wirklich zum Tragen kommt. Trotzdem wäre hier ja dann alternativ die format-Methode möglich, das wäre wohl auch lesbarer als mit join.
Ein wenig OT: Gibt es eigentlich ne Faustregel, wann man was (+, format, join) verwenden sollte?

P.S.: Das str() war bei meinem Ansatz nötig, da join nicht mit QStrings umgehen kann (was die Sache aber natürlich nicht besser macht ;))

Code: Alles auswählen

In [3]: "".join(['qt_', QtCore.QLocale.system().name()])
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-3-74911bb6ea8f> in <module>()
----> 1 "".join(['qt_', QtCore.QLocale.system().name()])

TypeError: sequence item 1: expected string, QString found
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

EmaNymton hat geschrieben:Gibt es eigentlich ne Faustregel, wann man was (+, format, join) verwenden sollte?
`join()` verwende ich, wenn ersichtlich sein soll, dass ich mehrere Strings in gleicher Weise verbinden möchte, also so Standards wie ``'\n'.join(...)`` oder ``'\t'.join(...)``.
`format()` nutze ich, wenn ich ein festes Schema mit Inhalt füllen möchte, auch wenn dieses feste Schema oft nur aus PunktKommaStrich besteht.
Für Operatoren entscheide ich mich eigentlich nur, wenn es tatsächlich einfach nur zwei Strings sind und ich das auch so im Code ausdrücken möchte.

IMHO halt...

mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
BlackJack

@EmaNymton: Zeichenketten sollte man nicht wiederholt mit ``+=`` oder ``x = x + val`` oder so ähnlich zusammenbauen. Weil bei jedem mal wo das gemacht wird eine neue Zeichenkette entsteht in die die beiden alten hinein kopiert werden, und die Datenmenge die da in der gegend herum kopiert wird, quadratisch steigt. Bei einer konstanten Anzahl von Zeichenketten und Operationen ist das vertretbar. Insbesondere wenn es zwei sind.

``+`` benutze ich eigentlich nur wenn ich schon Zeichenketten habe und die direkt zusammengefügt werden, oder wenn nur einer von zwei Werten mit `str()` umgewandelt werden muss und beide direkt zusammengefügt werden.
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

@EmaNymton: '+' benutze ich nur, wenn ich zwei/drei Strings zusammenpacken will, alles, was vorher noch in einen String konvertiert werden muss, mach ich per format. 'xy'.join wird nur benutzt, wenn schon Listen (variabler Länge) vorliegen.
Antworten