Fenster ohne Rahmen des Window-Manager starten.Nur Linux/KDE

Fragen zu Tkinter.
Antworten
egerlach
User
Beiträge: 41
Registriert: Samstag 14. März 2009, 21:32

Hallo,
ich will ein TKinter-Fenster öffnen, das NICHT den Rahmen des Window-Manager mit Titel, X zum schließen, _ zum klein-machen, u.s.w. hat. Es kannn das Fenster dann auch nicht mit der Maus verschoben werden, das ist gewollt so. Es soll das Fenster ganz und alleine durch eine Schaltfläche geschlossen werden können. Geht das mit TKinter?

Weiss jemand hier vielleicht wie man das im Fachjargon nennt, damit ich danach gezielt google'n kann?

Dann will ich noch, das Fenster an einer bestimmten Stelle positionieren und es muss eine bestimmte Größe haben. Das geht mit "geometry" und "place", so meine Recherchen in diesem Forum. Es soll das Fenster ausschließlich unter Linux/ KDE laufen/angezeigt werden, also kein Problem mit anderen Betriebsystemen


Gruss und ein Danke schon mal im voraus für alle Mitstreiter hier!
Eckard
yipyip
User
Beiträge: 418
Registriert: Samstag 12. Juli 2008, 01:18

Hallo Eckard,
was Du suchst, nennt sich
'overrideredirect',
z.B. hier:
http://epydoc.sourceforge.net/stdlib/Tk ... class.html

Eine kleine Demo:

Code: Alles auswählen

#!/usr/bin/env python

import Tkinter as tk

####

class Winit(object):
  
  def __init__(self, fullscreen=True, noborder=True, width=800, height=600, x=0, y=0):

    self.root = tk.Tk()
    
    if fullscreen:
      self.width = self.root.winfo_screenwidth()
      self.height = self.root.winfo_screenheight()
      self.x = 0
      self.y = 0
    else:
      self.width = width
      self.height = height
      self.x = x
      self.y = y
      
    self.root.geometry("%dx%d+%d+%d" % (self.width, self.height, self.x, self.y))
    self.root.wm_overrideredirect(noborder)

    self.button = tk.Button(text='Quit', command=self.root.quit)
    self.button.pack()
    

  def run(self):

    self.root.mainloop()

####

if __name__ == '__main__':

  Winit(False, True, 400, 300, 10, 20).run()

Bei 'overrideredirect(1)' sind (nach meinem Wissen) keine Key-Events möglich.

:wink:
yipyip
egerlach
User
Beiträge: 41
Registriert: Samstag 14. März 2009, 21:32

Ja genau das! Vorzüglichen Dank!
Und wenn ich rechts oben ins Eck will? - Bildschirmauflösung irgendwie auslesen und dann den Abstand von (0,0) oben links berechnen? - Gehts einfacher?
yipyip hat geschrieben: Bei 'overrideredirect(1)' sind (nach meinem Wissen) keine Key-Events möglich.
Was meinst Du damit? - Dass nach dem Klick auf "quit" nichts ausgeführt werden kann? - Also das, was ich machen will, ist eine Portierung von TK TCL auf python, TKinter ist ja gerade das TK TCL GUI, dann sollte es auch gehen.

Gruss
Eckard
Zuletzt geändert von egerlach am Sonntag 15. März 2009, 00:23, insgesamt 1-mal geändert.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

egerlach hat geschrieben:Und wenn ich rechts oben ins Eck will?
Achtung, die Positionierung von Fenstern ist die Sache des WMs und der muss sich nicht unbedingt reinreden lassen wo eine Applikation ihre Fenster gerne hätte - siehe etwa Tiling-WMs wo die Applikationen nicht gefragt werden wo sie positioniert werden wollen sondern einfach auf irgendeinen Bildschirmbereich gesteckt werden.

Hmm, das wäre fast wieder ein Kandidat für die FAQ...
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
egerlach
User
Beiträge: 41
Registriert: Samstag 14. März 2009, 21:32

Leonidas hat geschrieben:
egerlach hat geschrieben:Und wenn ich rechts oben ins Eck will?
Achtung, die Positionierung von Fenstern ist die Sache des WMs und der muss sich nicht unbedingt reinreden lassen wo eine Applikation ihre Fenster gerne hätte - siehe etwa Tiling-WMs wo die Applikationen nicht gefragt werden wo sie positioniert werden wollen sondern einfach auf irgendeinen Bildschirmbereich gesteckt werden.
Siehe subject, ich muss nur KDE überreden das zu tun. Gibt es so etwas wie "screenwidth" (TK TCL) um Bildschirmhöhe und -breite auszulesen?

in http://www.koders.com/python/fidF15A104 ... f%3Ainsert gefunden:

Code: Alles auswählen

[...]
import wx
[...]
screenWidth = wx.SystemSettings.GetMetric(wx.SYS_SCREEN_X)
screenHeight = wx.SystemSettings.GetMetric(wx.SYS_SCREEN_Y)
ich probiers mal aus .. bin da aber noch nicht so fit ;-) muss erstmal wx finden wo es das gibt .. Oder weiss sonst jmd wie man screenWidth ausliest?
yipyip
User
Beiträge: 418
Registriert: Samstag 12. Juli 2008, 01:18

Guck' mal in meine Demo....
:wink:
yipyip
Benutzeravatar
Trundle
User
Beiträge: 591
Registriert: Dienstag 3. Juli 2007, 16:45

egerlach hat geschrieben:Siehe subject, ich muss nur KDE überreden das zu tun. Gibt es so etwas wie "screenwidth" (TK TCL) um Bildschirmhöhe und -breite auszulesen?
Ich nutze auch KDE. Und einen Tiling Window Manager. Das muss sich ja nicht ausschließen.

Solche Dinge wie Positionierung und Größe sind eigentlich nur Empfehlungen. Wenn der WM nett zum Programm ist, beachtet er sie, aber verlassen kann sich das Programm darauf nicht (dann ist der WM nett zum Benutzer).
"Der Dumme erwartet viel. Der Denkende sagt wenig." ("Herr Keuner" -- Bertolt Brecht)
egerlach
User
Beiträge: 41
Registriert: Samstag 14. März 2009, 21:32

:lol: Danke! Ich hatte wohl Tomaten auf den Augen!

Habe oben in meine Antwort auf Dein Beispiel nun noch etwas eingefügt (was man eigentlich nicht macht, ich weiss), nämlich was Du mit "event evtl. nicht möglich" meinst. Kannst Du noch präzisieren, was Du damit meinst?
egerlach
User
Beiträge: 41
Registriert: Samstag 14. März 2009, 21:32

Trundle hat geschrieben: Solche Dinge wie Positionierung und Größe sind eigentlich nur Empfehlungen. Wenn der WM nett zum Programm ist, beachtet er sie, aber verlassen kann sich das Programm darauf nicht (dann ist der WM nett zum Benutzer).
Also gemäß dem Beispiel oben funktioniert es unter KDE 3.x hier bestens. Aber danke auch für den Hinweis, es muss unter jedem WM halt getestet werden.
Benutzeravatar
Trundle
User
Beiträge: 591
Registriert: Dienstag 3. Juli 2007, 16:45

Das ist recht unpräzise. KDE benutzt auch einen WM. Und das ist nicht immer derselbe, den kann man problemlos austauschen. Also sind solche Aussagen wie "läuft unter KDE 3.x" immer so eine Sache.
"Der Dumme erwartet viel. Der Denkende sagt wenig." ("Herr Keuner" -- Bertolt Brecht)
yipyip
User
Beiträge: 418
Registriert: Samstag 12. Juli 2008, 01:18

Die Buttons funktionieren mit
'overrideredirect(1)'.
Diesen Befehl habe ich so verstanden, dass dieses Fenster vom
Window-Manager ignoriert wird und somit auch keine
Tastaturereignisse entgegennehmen kann.
(Jedenfalls bei mir unter XFCE, vielleicht ist das bei anderen WM's anders.)

http://wiki.tcl.tk/9870
yipyip
User
Beiträge: 418
Registriert: Samstag 12. Juli 2008, 01:18

Das Problem ist:
Das undekorierte Fenster bekommt nicht den Focus!
Die wenigen Antworten, die ich ergoogeln konnte,
schlagen 'focus_set()' und 'focus_force()' vor,
bei mir funktioniert das jedoch nicht.
Andere WM's habe ich momentan auch nicht zur Verfügung...

Die Demo dazu:
http://paste.pocoo.org/show/108103/

Mit
Winit(1, 0, 400, 300, 10, 20).run()
gibt's Tastaturevents;
mit
Winit(1, 1, 400, 300, 10, 20).run()
nicht.


:wink:
yipyip
yipyip
User
Beiträge: 418
Registriert: Samstag 12. Juli 2008, 01:18

Tja, wenn man sich lange genug damit beschäftigt,
dann klappt's auch:
Ich nehme alles zurück und behaupte das Gegenteil!
:D

Hier die Demo:
http://paste.pocoo.org/show/108759/

Achtung, die Demo sperrt den gesamten Bildschirm,
aber zum Glück gibt's ja einen Quit-Button.

:wink:
yipyip
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hallo Tkinter-Freunde

Habe den Code von 'yipyip' noch erweitert. Das rahmenlose Fenster ist jetzt mit der Maus verschiebbar:

[Code ausgelagert]

Wie schon von 'yipyip' erwähnt wurde blockiert das Skript den Rest des Desktops !!! Kann nur durch beenden des Skriptes mittels Schaltfläche 'Quit' normalisiert werden.

Gruss wuf :wink:
Take it easy Mates!
yipyip
User
Beiträge: 418
Registriert: Samstag 12. Juli 2008, 01:18

Hallo wuf,
Danke für die sinnvolle Ergänzung.

Was mir aufgefallen ist:
Nicht nur das Root-Window, sondern auch
das Button- und Label-Widget erzeugen
Enter- und Leave-Events.
Da dies von Deiner Programmlogik nicht
berücksichtigt wird, kann es passieren,
dass das Fenster nicht verschiebbar
ist, obwohl der Mauszeiger darin ist.
(Und zwar immer dann, wenn der Mauszeiger
den Button oder das Label verlassen hat.)

Hier nochmal eine leicht modifizierte Version:
http://paste.pocoo.org/show/109097/

:wink:
yipyip
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hallo yipyip

Danke für deine Code-Verbesserungen. Ich habe das Skript bereinigt. Die Methoden .update_idletasks() entfernt usw.

[Code ausgelagert]

Ein unschöner Effekt bleibt aber bestehen. Ein aktive Anwendung gibt den Focus beim start unseres Skriptes nicht ab. Das heisst funktionell schon aber nicht visuell. Ich meine damit, dass die Titelleiste der aktiven Anwendung ihre Farbe nicht von blau auf grau ändert. Dies ist nur der Fall, wenn das Hauptfenster unseres Skriptes sichbar auf dem Desktop vorhanden ist. Das Hauptfenster mit den Methoden .withdraw bzw. .iconfiy vom Desktop zu entfernen bzw. verstecken bring es nicht. Ich habe unser Skript noch ein wenig erweitert. Ich füge ein Hauptfenster hinzu reduziere es auf ein Minimum und verstecke es hinter dem rahmenlosen Dialogfenster (jetzt als Toplevelfenster). Beim verschieben des Dialogfensters verschiebt sich auch das reduzierte Hauptfenster hinter dem Dialogfenster. Hier das modifizierte Skript:

[Code ausgelagert]

P.S. Übrigens danke noch für dein Link auf den Beschrieb des 'socket'- Moduls

Gruss wuf :wink:
Take it easy Mates!
yipyip
User
Beiträge: 418
Registriert: Samstag 12. Juli 2008, 01:18

Hallo wuf,
gute Idee, wie man den Window-Manager austricksen kann... :wink:

Bei der Ausgangsfrage des OP's dachte ich eher an so etwas wie
einen Kiosk-Modus, also ein Fullscreen-Window ohne Rahmen,
das alle Maus- und Tastaturereignisse abfängt.
Wie wir (mittlerweise) wissen, ist das ja kein Problem mit Tkinter...

:wink:
yipyip
yipyip
User
Beiträge: 418
Registriert: Samstag 12. Juli 2008, 01:18

Hier noch eine kleine Spielerei:

http://paste.pocoo.org/show/111438/

Ein Klick mit der linken Maustaste auf das Popup-Fenster
beendet das Programm.

:wink:
yipyip
Antworten