Seite 1 von 1

PyQt Programm aktiv starten

Verfasst: Freitag 19. Februar 2010, 13:38
von mzh
Hallo zusammen
Ich habe ein Programm (aus "Rapid Gui Programming with PyQt") geschrieben:

Code: Alles auswählen

#!/usr/bin/pythonw

#How to set the focus to the application?

from __future__   import division
import sys
from math         import *
from PyQt4.QtCore import *
from PyQt4.QtGui  import *

class Form(QDialog):
    def __init__(self, parent=None):
        super(Form, self).__init__(parent)

        self.browser  = QTextBrowser()
        self.lineedit = QLineEdit("Type an expression and press Enter")
        self.lineedit.selectAll()

        layout        = QVBoxLayout()
        layout.addWidget(self.lineedit)
        layout.addWidget(self.browser)

        self.setLayout(layout)
        self.lineedit.setFocus()
        #widget: self.lineedit,
        #SIGNAL: returnPressed(),
        #slot: self.updateUi 'of Form'.
        self.connect(self.lineedit, SIGNAL("returnPressed()"),
                self.updateUi)
        self.setWindowTitle("Calc.pyw")

    def updateUi(self):
        #catch all exception
        try:
            text = unicode(self.lineedit.text())
            self.browser.append("%s = <b>%s</b>" % (text, eval(text)))
        except:
            self.browser.append(
                    "<font color=red>%s is invalid!</font>" % text)

app = QApplication(sys.argv)
form = Form()
app.setActiveWindow(form)
#Does not work to set the focus on the application.
#form.setFocus()
form.show()
app.exec_()
Wenn ich das aus dem Terminal mit
$ calc.pyw
aufrufe, bleibt der Fokus leider im Terminal und ich muss erst UMSTÄNDLICH die Maus bemühen und das kleine Widget aktivieren damit ich tippen kann. Wie kann ich erreichen, dass das Widget sofort aktiv ist, wenn ich das Programm ausführe?

Vielen Dank für hilfreiche Beiträge.

Verfasst: Freitag 19. Februar 2010, 13:47
von cofi
Kann ich nicht nachvollziehen.
Allerdings ist deine Shebang falsch: Es gibt kein `pythonw` bei Unices. Und `#!/usr/bin/env python` ist die bessere Variante.

Verfasst: Freitag 19. Februar 2010, 13:52
von mzh
ok, hm, also ich kann im Terminal (Mac OS X 10.5) pythonw tippen und Python startet, schaus mir aber an.
Was kannst du nicht nachvollziehen? Meine Frage oder wieso ich mit dem gezeigten Code das Problem wie geschildert habe?

Verfasst: Freitag 19. Februar 2010, 14:25
von philistion
Mit der setFocus() Funktion setzt man ja nur den Fokus im Fenster auf ein bestimmtes Steuerelement, wie hier eben auf dein TextEdit.

Schau dir mal Qt.WindowState an, damit müsste man den Keyboard-Focus auf das Fenster setzen können: http://www.riverbankcomputing.co.uk/sta ... State-enum

Verfasst: Freitag 19. Februar 2010, 14:58
von mzh
danke für die Hinweise.

Code: Alles auswählen

Qt.WindowActive	0x00000008	The window is the active window, i.e. it has keyboard focus.
Ich nehme an, man setzt also einen Hex-Wert?

Verfasst: Freitag 19. Februar 2010, 16:31
von Klip
Eher die Konstante ;)

Code: Alles auswählen

>>> QtCore.Qt.WindowStates
<class 'PyQt4.QtCore.WindowStates'>
>>> QtCore.Qt.WindowActive
8
Ist lesbarer als ein Zahlenwert (:

Verfasst: Samstag 20. Februar 2010, 00:24
von mzh
hm, ich bin nicht sicher, ob ich folgen kann.
Ok, die Konstante hat den Wert 8, was kann ich nun damit anfangen?
Sorry für die blöde Frage.
Kann es sein, dass das auch mit dem Art wie der Python Launcher konfiguriert ist zu tun hat?

Verfasst: Sonntag 21. Februar 2010, 13:21
von ichisich
Ein QWidget hat die Methode

Code: Alles auswählen

void QWidget::setWindowState ( Qt::WindowStates windowState )
mit der Du die Konstante setzen kannst.

Verfasst: Sonntag 21. Februar 2010, 14:38
von philistion
@mzh: Da du scheinbar in den Grundlagen noch nicht ganz fix bist, wäre es vielleicht besser erstmal ein Tutorial gründlich durchzuarbeiten. Dann ist dir auch aus unseren Postings klar, was du tun musst ;)
Du kannst z.B. dieses hier nehmen: http://tutorial.pocoo.org

Aber zurück zum Thema:
Ich habe es bei mir unter Linux ausprobiert, die Methode zeigt nicht die erwünschte Wirkung. Es kann sein, dass dies an meiner Desktopumgebung liegt. Laut Dokumentation sollte diese Funktion genau diesen Effekt haben.
Vielleicht kann dies jemand mal unter Windows versuchen, also im Widget-Konstruktor

Code: Alles auswählen

self.setWindowState(Qt.WindowActive)
ausführen.

Verfasst: Sonntag 21. Februar 2010, 14:43
von lunar
Um ein Fenster zu aktivieren, gibt es "QWidget.activateWindow()". Benutzt werden sollte diese Methode in Verbindung mit "QWidget.raise()", damit das aktive Fenster auch oben liegt:

Code: Alles auswählen

self.raise()
self.activateWindow()
Unter Windows führt das nur dazu, dass der Taskleisen-Eintrag zu Blinken anfängt. Unter Linux ist das Resultat abhängig vom verwendeten Window-Manager und dessen Konfiguration.

Verfasst: Sonntag 21. Februar 2010, 14:55
von philistion
Ah, jetzt weiß ich nach Lesen dieses Artikels endlich was der Fehler war.

Das ist der funktionierende Code bei QDialog:

Code: Alles auswählen

self.setWindowState(Qt.WindowActive)
self.show()
Man kann aber natürlich auch

Code: Alles auswählen

self.activateWindow()
self.show()
verwenden, geht genauso.

Verfasst: Dienstag 23. Februar 2010, 09:29
von mzh
danke für die Posts soweit.
Mein System ist Mac OS X 10.5.

Code: Alles auswählen

self.setWindowState(Qt.WindowActive)
self.show()
Ich nehme an, das gehört am besten in die __init__() Methode?

@philistion: ja, das beispiel ist ja aus einem tutorial... Wie gesagt, die Wirkung des Programms ist wie erwartet, nur meine Umgebung zwingt Python zu dem unerwünschten Verhalten, den Dialog nicht im Fokus zu öffnen.
Btw., was ist denn der Unterschied zwischen einer .py und einer .pyw Extension?

Verfasst: Dienstag 23. Februar 2010, 11:28
von philistion
Ja genau!

.pyw führt z.B. bei Windows dazu, dass das Programm ohne eine Python-Konsole geöffnet wird, was v.a. bei GUI-Anwendungen praktisch ist.
Unter Linux hat das, soweit ich das jetzt beobachtet habe, keine Auswirkungen.

Verfasst: Dienstag 23. Februar 2010, 11:55
von mzh
ok. Der Grund für diese Frage zu show() ist, dass bis jetzt show() meist im "Ausführungsbereich" des Skriptes gecalled wurde.
Ich bin aber nicht sicher, ob ich die Bedeutung von show() verstehe.

Verfasst: Dienstag 23. Februar 2010, 21:24
von lunar
Bitte "aufgerufen" oder so, aber "gecalled" (auch noch mit englische Deklination) ist einfach furchtbar :)

".show()" sorgt einfach nur dafür, dass das Fenster überhaupt angezeigt wird. Wo, wie und ob im Vorder- oder Hintergrund ist danach Sache des Fenstersystems. Gerade unter Unix-Systemen gibt es da alle möglichen Spielarten …
mzh hat geschrieben:ok. Der Grund für diese Frage zu show() ist, dass bis jetzt show() meist im "Ausführungsbereich" des Skriptes gecalled wurde.
Ich bin aber nicht sicher, ob ich die Bedeutung von show() verstehe.