2017-08-24 1 views
0

Ich stoße in WxPython auf etwas störendes Verhalten mit modalen Frames. Wie wir alle wissen, erscheint ein modales Fenster im Vordergrund (oben auf dem Hauptfenster) und das Hauptfenster sollte nicht mehr zugänglich sein (keine Antwort zum Klicken zum Beispiel).WxPython - Ungenaues modales Windows-Verhalten

Dies funktioniert wie erwartet mit verschachtelten WxFrames, bis die Windows-Startleiste (Status) verwendet wird. Wenn der Benutzer auf den Hauptrahmen in der Windows-Leiste klickt, erscheint er über dem zweiten Rahmen, was völlig ungenau ist, da der Benutzer nicht versteht, was passiert und warum das Fenster nicht zugänglich ist.

Die erste Lösung, die mir in den Sinn kommt, ist, das Aktivierungsereignis des ersten Frames zu binden und programmatisch (& systematisch) den zweiten Frame in den Vordergrund zu setzen. Es erscheint mir jedoch merkwürdig, dass dieses Verhalten nicht schon von WxPython auf natürliche Weise gemacht wird.

Hat jemand eine Idee oder eine native/generische Lösung dafür?

+0

"verschachtelte modale Rahmen" klingt von Anfang an nach einer schrecklichen Idee. Du könntest gut in der verwirrenden Position enden, in der du nach jemandem suchst, der eigentlich den Fokus hat. –

+0

Vergessen Sie das Wort "verschachtelt"! Ich werde dieses Wort aus dem Titel entfernen, wenn es verwirrend ist. Dieses Problem tritt sogar mit nur "einem" modalen Rahmen auf und ich denke nicht, dass es eine schreckliche Idee ist, ein modales Fenster zu verwenden. –

+0

Ein modales Fenster blockiert alle anderen Workflows im Programm der obersten Ebene, bis das modale Fenster geschlossen wird. Modale Fenster sollen die volle Aufmerksamkeit des Benutzers erregen. Benutzer erkennen möglicherweise nicht, dass ein modales Fenster ihre Aufmerksamkeit erfordert, was zu Verwirrung über das Hauptfenster führt, das nicht reagiert. In schweren Fällen erscheint das modale Fenster hinter einem anderen Fenster, das von demselben Programm gesteuert wird, wodurch möglicherweise das gesamte Programm nicht mehr reagiert, bis das modale Fenster manuell gefunden werden kann. https://en.wikipedia.org/wiki/Modal_window –

Antwort

0

Wie ich in meiner Frage vorgeschlagen, bin ich Ereignis aktivieren Ich hebe alle Kinder Fenster gebunden. Dies funktioniert wie erwartet. Wir können zuerst zum Fenster der obersten Ebene gehen und beginnen, vom ersten Fenster aus zu erhöhen, um immer alle Kinderrahmen anzuheben. Aber immer ist es komisch für mich, dass es nicht von wxPython verwaltet wird.

def __init__(self, parent): 
    wx.Frame.__init__(...) 
    ... 
    self.Bind(wx.EVT_ACTIVATE, self.on_activate_window) 

def on_activate_window(self, event): 
    """ 
    Set modal windows to foreground by their hierarchical order 
    """ 
    self.set_children_to_top(self.GetChildren()) 

def set_children_to_top(self, children): 
    """ 
    Loops all children of the given windows, if any other modal window is found, it raises the new window to foreground 
    """ 
    for child in children: 
     if isinstance(child, wx.Frame) and child.is_modal: 
      child.Raise() 
     try: 
      child_window = child.GetChildren() 
      if child_window: 
       self.set_children_to_top(child_window) 
     except AttributeError: 
      continue 
0

Es ist viel besser wx.Dialog zu verwenden, wenn Sie ein modales Fenster müssen, wie es von Anfang an so konzipiert ist, dass Art und Weise zu verhalten. In der Tat wurde wegen der Inkonsistenzen die MakeModal Methode für Frames entfernt, obwohl, wenn Sie es wirklich so tun müssen, gibt es eine Problemumgehung.

+0

Wir haben ein riesiges Projekt, wo wir viele wxFrame haben. Ich denke also nicht, dass es sicher und einfach wäre, alle nach wxDialog zu migrieren (ehrlich gesagt bevorzuge ich meine Problemumgehung). Außerdem, soweit ich weiß, wxFrame ist das Hauptfenster einer App, mit einer Menüleiste, Symbolleiste und Statusleiste. Alle diese Funktionen werden von wxDialog nicht nativ unterstützt. –