Seite 1 von 1

Problem mit Dialogen: Sie sind immer im Vordergrund.

Verfasst: Dienstag 29. November 2005, 20:06
von amarganth
Hi wxPythonGurus

Ich kämpfe seit Tagen mit einem Problem: Ich versuche einen Dialog zu erzeugen, der nicht immer in Front des Haupt-Frames steht. Wenn ich auf das Hauptframe klicke, möchte ich, dass der Dialog in den Hintergrund entschwindet. Ich kriege das einfach nicht hin. :?

Hier das Codebeispiel:

Code: Alles auswählen

import wx

class MyDialog1(wx.Dialog):
    def __init__(self, parent, id):
        sty = wx.DEFAULT_DIALOG_STYLE | wx.DIALOG_NO_PARENT
        wx.Dialog.__init__(self, parent, id, "MyDialog parent", 
            wx.Point(30,120), wx.Size(180, 100), style=sty)

class MyDialog2(wx.Dialog):
    def __init__(self, parent, id):
        sty = wx.DEFAULT_DIALOG_STYLE | wx.DIALOG_NO_PARENT
        wx.Dialog.__init__(self, None, id, "MyDialog None", 
            wx.Point(230,120), wx.Size(180, 100), style=sty)

class MyPanel(wx.Panel):
    def __init__(self, parent, id):
        wx.Panel.__init__(self, parent, id, wx.DefaultPosition, 
            wx.DefaultSize)
        b1 = wx.Button(self, 1001, "Open dialog window with parent", 
            wx.Point(8, 8))
        b1.Bind(wx.EVT_BUTTON, self.OnClick1)
        b2 = wx.Button(self, 1002, "Open dialog window with None parent",
            wx.Point(8, 38))
        b2.Bind(wx.EVT_BUTTON, self.OnClick2)

    def OnClick1(self, event):
        self.dlg1 = MyDialog1(self, -1)
        self.dlg1.Show(True)  
        
    def OnClick2(self, event):
        self.dlg2 = MyDialog2(self, -1)
        self.dlg2.Show(True)  
        
class MyFrame(wx.Frame):
    def __init__(self, parent, id):
        wx.Frame.__init__(self, parent, id, "MyFrame", 
            wx.Point(20, 20), wx.Size(300, 150))
        self.pa = MyPanel(self,-1)

class MyApp(wx.App):
    def OnInit(self):
        frame = MyFrame(None, -1)
        frame.Show(True)
        self.SetTopWindow(frame)
        return True

def main():
    app = MyApp(0)
    app.MainLoop()

if __name__ == '__main__':
    main()
Wenn ich den Dialog1 (with parent) öffne und wieder schliesse, läuft alles wunderbar. Sobald ich Dialog2 (with None parent) öffne, klappt das zwar, dass es beim Klicken auf das Hauptframe in den Hintergrund geht, aber das Programm endet nur mit abwürgen.

Das Style-Flag "wx.DIALOG_NO_PARENT" scheint keinen Einfluss zu haben. Dialog 1 hat ja wohl trotzdem ein Parent.

Ich arbeite unter Windows XP SP2. Python hat die Version 2.3.4, wxPython die Version 2.6.1.0.

Für Tipps irgendwelcher Art bin ich dankbar.

amarganth

Verfasst: Mittwoch 30. November 2005, 10:12
von Francesco
Ja, ich sehe das Problem, wess leider auch keine Lösung dafür.

Aber wie wäre es, wenn du ein neues Frame verwendest und da den Dialog
drauf erstellst? Das verschwindet dann, wenn das Haupframe den Focus
erhält.(?) :idea:

Verfasst: Mittwoch 30. November 2005, 23:32
von amarganth
Hi Francesco und all die anderen Leser

Die Idee ist ja gut, auch wenns, hmm, eine ästhetisch suboptimale Lösung ist. Nur: es funktioniert auch auf diese Weise nicht.

Zur Kontrolle hier der Code mit einem hidden frame2. Um das zweite Frame referenzieren zu können, habe ich es jeweilen global angesprochen, wo ich es benötigte. Es reagiert unter Windows XP seltsam: Jedes zweite Mal knallts und reisst mir die ganze IDE runter. Wenn ich diese neu starte, funktioniert's wieder 1x, und dann knallt's wieder.

Hier der Code, so kurz als möglich:

Code: Alles auswählen

import wx

class MyDialog1(wx.Dialog):
    def __init__(self, parent, id):
        sty = wx.DEFAULT_DIALOG_STYLE
        wx.Dialog.__init__(self, parent, id, "MyDialog parent", 
            wx.Point(30,120), wx.Size(180, 100), style=sty)

class MyDialog2(wx.Dialog):
    def __init__(self, parent, id):
        sty = wx.DEFAULT_DIALOG_STYLE
        wx.Dialog.__init__(self, parent, id, "(hidden frame parent)", 
            wx.Point(230,120), wx.Size(180, 100), style=sty)

class MyFrame(wx.Frame):
    def __init__(self, parent, id):
        wx.Frame.__init__(self, parent, id, "MyFrame", 
            wx.Point(20, 20), wx.Size(300, 150))
        b1 = wx.Button(self, 1001, "dialog window with parent", wx.Point(8, 8))
        b1.Bind(wx.EVT_BUTTON, self.OnClick1)
        b2 = wx.Button(self, 1002, "dialog window with hidden frame parent", 
            wx.Point(8, 38))
        b2.Bind(wx.EVT_BUTTON, self.OnClick2)
        self.Bind(wx.EVT_CLOSE, self.OnFrameClose)

    def OnClick1(self, event):
        self.dlg1 = MyDialog1(self, -1)
        self.dlg1.Show(True)  
        
    def OnClick2(self, event):
        global frame2
        self.dlg2 = MyDialog2(frame2, -1)
        self.dlg2.Show(True)  
        
    def OnFrameClose(self, event):
        global frame2
        frame2.Destroy()
        self.Destroy()
        
class MyHiddenFrame(wx.Frame):
    def __init__(self, parent, id):
        wx.Frame.__init__(self, parent, id, "MyHiddenFrame", 
            wx.Point(330, 20), wx.Size(300, 150))
        
class MyApp(wx.App):
    def OnInit(self):
        frame = MyFrame(None, -1)
        frame.Show(True)
        self.SetTopWindow(frame)
        global frame2
        frame2 = MyHiddenFrame(None, -1)
        frame2.Hide() 
        return True

app = MyApp(0)
app.MainLoop()

Verfasst: Donnerstag 1. Dezember 2005, 13:36
von Francesco
Es reagiert unter Windows XP seltsam: Jedes zweite Mal knallts und reisst mir die ganze IDE runter. Wenn ich diese neu starte, funktioniert's wieder 1x, und dann knallt's wieder.
Kannst du das genauer erklären?
Wie startest du die? direkt vom command prompt?
Welche IDE? meinst du crash? oder friert sie ein?

Verfasst: Donnerstag 1. Dezember 2005, 15:54
von Gast
Ich versuch's:

Ich starte die IDLE, dann mein Demoprogramm. Das erste Mal klappts, ich spiele mit den Fenstern, schliesse sie, gerate auf den Command Prompt der IDLE zurück. Dann starte ich das Demoprogramm nochmals. Bereits beim Aufbau und beim Herumschieben der Fenster sehe ich, dass der Hintergrund (also die IDLE) nicht mehr sauber refreshed wird. Nach dem Schliessen aller Fenster ist die IDLE blockiert. Beenden kann ich sie dann nur, wenn ich mit der rechten Maustaste auf die XP-Taskbar klicke (kein Witz, sorry). Dann kommt ein Python Runtime Error und die IDLE und das Programm sind weg.

Zu gerne würde ich erfahren, wie sich obiges Beispiel unter Linux verhält.

Ich hoffe, Dir reichen diese Angaben.

Verfasst: Donnerstag 1. Dezember 2005, 16:13
von Francesco
Auf jeden Fall: Idle (Tkinter) und wxPython vertragen sich sowieso
nicht gut. Du solltest einen eigenen Editor wie SciTE verwenden.

Wenn das nicht hilft, vielleicht die wxPython mailing list versuchen ...

welche wxPython Version verwendest du übrigens?
aktuell ist 2.6.1 oder auch 2.6.0.

Verfasst: Donnerstag 1. Dezember 2005, 17:47
von amarganth
Hi Francesco
Ich arbeite unter Windows XP SP2. Python hat die Version 2.3.4,
wxPython die Version 2.6.1.0.
Nun, Du hast mir geholfen. Danke! :D Gestartet ab der Command Line funzt das ganze. Mein ursprüngliches Beispiel endet nie und muss abgebrochen werden, Das Beispiel auf Grund Deines Tipps mit dem hidden frame endet ganz normal.

Ich habe trotzdem noch etwas ein ungutes Gefühl. :? Ich baue es jetzt mal auf diese Weise in meine "richtige" Anwendung ein. :oops:

Ansonsten gerate ich an die Newsgruppe.

amarganth