Abfrage ob Fenster bereits offen

Fragen zu Tkinter.
Antworten
KillingTears
User
Beiträge: 7
Registriert: Freitag 10. April 2009, 01:45

Hi ich habe folgendes Problem:

Ich habe eine Listbox in der Namen stehen . Wenn ich auf den Name klicke öffnet sich ein neues Fenster namens Profil welches zuvor den Namen als Parameter übergeben bekommen hat .

Nun möchte ich , dass wenn man wieder auf den selben Namen klickt sich das bereits offene Fenster nach vorne hebt aber sich kein neues Fenster öffnet. Allerdings habe ich keine Idee wie ich das machen könnte.

Weiss jemand von euch wie ich das erreichen könnte?
BlackJack

@KillingTears: *Du* öffnest ja das neue Fenster, also kannst Du Dir ja auch merken dass Du es geöffnet hast. Zum Beispiel in dem Du das Fenster-Objekt an einen Namen bindest an den sonst `None` gebunden ist. Beim schliessen des Fensters musst Du dann nur wieder dafür sorgen, dass der Name wieder an `None` gebunden wird, und schon weisst Du immer ob das Fenster gerade offen ist oder nicht.
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hallo KillingTears

Hier etwas vom Osterhasen zum herumspielen:
(Nur getestet unter Linux)

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

Frohe Ostern. Gruss wuf :wink:
Take it easy Mates!
KillingTears
User
Beiträge: 7
Registriert: Freitag 10. April 2009, 01:45

Vielen Dank und ebenfalls Frohe Ostern ^^. Der Code klappt soweit auch unter Windows.

Habe den Code zwar verstanden allerdings stehe ich grad ein wenig auf dem Schlauch weil meine Daten in der Listbox aus einer Datenbank kommen und somit also auch Xbeliebige größen annehmen.

Das Problem dabei ist bei mir , dass profile_dict = {NAME_A:None, NAME_B:None, NAME_C:None} ja ziemlich statisch ist und ich das dynamisch kriegen muss sofern ich den Code richtig verstanden habe.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Meinst du das?

Code: Alles auswählen

profile_dict["new_key"] = "new_value"
Das steht nämlich auch im Standardtutorial.
Das Leben ist wie ein Tennisball.
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hallo KillingTears

Ich bin leider kein Datenbank-Spezialist. Aber ich nehme an du könntest die einzelnen Profilnamen in die profile_list einlesen und anschliessend mit einer for-Schleife das profile_dict dynamisch mit den Profilnamen aus der profile_list als Schlüsselwörter 'new_key' erstellen. Jedem Schlüsselwort ist bei der Erstellung gleichzeitig der Wert None 'new_value' zuzuweisen. So wie es EyDu bereits angedeutet hat.

Gruss wuf :wink:
Take it easy Mates!
KillingTears
User
Beiträge: 7
Registriert: Freitag 10. April 2009, 01:45

Soweit sollte es nun eigentlich klappen tut es aber nicht.

Ich weiss auch den Grund dafür , das dict wird zwar wunderbar angelegt aber der Wert des Fensters wird erst nach dem schließen des Gesamtprogrammes übergeben(hab das durch ausgeben der tkMessageBox herausgefunden) .

Zuerst dachte ich daran dass es daran liegt das
profile_dict={} global liegt , aber selbst das schlüsselwort global scheint keinen erfolg zu geben . Hier mal der Codeausschnitt wo ich übergebe:

Code: Alles auswählen


    def prae_profile(self,buffer,userid):
        friendname = str(self.online.get(self.online.curselection()))
        global profile_dict
        if profile_dict[friendname] is None:
            #Neues Fenster anlegen falls es noch nicht existiert
            tkMessageBox.showerror(friendname,profile_dict) # werte sind immer Name der  User : None ob nun das Fenster bereits offen ist oder nicht.
            
            profile_dict[friendname] = Profile(userid,friendname)
            tkMessageBox.showerror(friendname,profile_dict) # wird erst nach dem schließen des gesamtprogramms ausgeführt und gibt dann an das es sehr wohl gespeichert wurde nur leider zu spät
        else:
           #Fenster bereits offen ... hebt es hervor
            app_win.update()
            profile_dict[friendname].lift()
            profile_dict[friendname].transient(app_win)
            profile_dict[friendname].focus_set() 
        
Und an dieser Stelle fülle ich die dict dabei beinhaltet rows[1] die namen der user . Das klappt auch soweit wie die ausgabe der tkMessageBox zeigt.

Code: Alles auswählen

self.online.insert(END,rows[1])
if rows[1] not in profile_dict:
               profile_dict[rows[1]] = None
BlackJack

Vergiss am besten, dass es ``global`` gibt. Wenn man das wirklich braucht, ist es meistens keine gute Idee.

Was machst Du denn in `Profile.__init__()`, dass dort blockiert wird?
KillingTears
User
Beiträge: 7
Registriert: Freitag 10. April 2009, 01:45

dort wird lediglich ein Toplevelfenster erstellt und die Profildaten werden aus der Datenbank gelesen und das Avatar wird via PIL angezeigt.
BlackJack

Aber irgend etwas musst Du da machen was die Rückkehr des Aufrufs verhindert.
KillingTears
User
Beiträge: 7
Registriert: Freitag 10. April 2009, 01:45

Naja ich wüsste nicht was aber hier mal der code der Profile.__ini__ :

Code: Alles auswählen


def __init__(self,friendname):
        
        #master4 = Tk(screenName="Profil",className="Profil: "+friendname)
        Toplevel.__init__(self)
        self.title("Profil: "+friendname)
        self.attributes("-alpha",0.8)
        
        self.geometry("800x500")
        self.iconbitmap('msgico.ico')
        self.config(bg="#000000",)
        
        conn = MySQLdb.connect (host = "localhost",
                        user = "root",
                        passwd = "",
                        db = "armyofdragon")
        cursor = conn.cursor ()
        sql="SELECT firstname, lastname, website, location, occupation, interests, company, address, city, state, phone, fax FROM jos_users, jos_comprofiler WHERE jos_users.id = user_id AND username = '" + friendname + "';"
        sql2="Select avatar from jos_users,jos_comprofiler WHERE jos_users.id=user_id AND username='" + friendname + "';"

        cursor.execute (sql)

        profil = cursor.fetchone ()
        
        header = tkFont.Font ( size="48")

        
        cursor.execute (sql2)
        ava1 = cursor.fetchone ()
        if ava1[0] is None :
            urlString = "http://www.armyofdragon.de/images/messenger/noavamsg.png"
            bild = "noavamsg.png"
            
        else:
            urlString = "http://www.armyofdragon.de/images/comprofiler/"+str(ava1[0])
            bild = str(ava1[0])
        imgStream = urllib.urlretrieve(urlString,"images\\"+bild)
        
        rechts = Frame(self,bg="#000000")
        rechts.pack(anchor=E,fill=BOTH,side=RIGHT,expand=YES)
        links = Frame(self,bg="#000000")
        links.pack(anchor=W,fill=BOTH,expand=YES)
        
        self.labelprofilname = Label(links ,font=header,bg="#000000",fg="#FF0000", text=friendname)
        self.labelprofilname.pack(anchor=N)
        
        Avatar = Imageload.PhotoImage(IMG.open("images\\"+bild).resize((80,80)),master=self) 
        self.avatarprofil = Label (rechts,text="AVA",image=Avatar).pack(anchor=N)
        self.label1= Label(links , text="Vorname: ",bg="#000000",fg="#FF0000").pack(anchor=W)
        self.text1= Label(links , text=profil[0],bg="#000000",fg="#FF0000").pack(anchor=W)
        self.label2= Label(links , text="Nachname: ",bg="#000000",fg="#FF0000").pack(anchor=W)
        self.text2= Label(links , text=profil[1],bg="#000000",fg="#FF0000").pack(anchor=W)
        self.label3= Label(rechts , text="Website: ",bg="#000000",fg="#FF0000").pack(anchor=W)
        self.text3= Label(rechts , text=profil[2],bg="#000000",fg="#FF0000").pack(anchor=W)
        self.label4= Label(links , text="Lokation: ",bg="#000000",fg="#FF0000").pack(anchor=W)
        self.text4= Label(links , text=profil[3],bg="#000000",fg="#FF0000").pack(anchor=W)
        self.label5= Label(rechts , text="Beruf: ",bg="#000000",fg="#FF0000").pack(anchor=W)
        self.text5= Label(rechts , text=profil[4],bg="#000000",fg="#FF0000").pack(anchor=W)

        self.label7= Label(rechts , text="Firma: ",bg="#000000",fg="#FF0000").pack(anchor=W)
        self.text7= Label(rechts , text=profil[6],bg="#000000",fg="#FF0000").pack(anchor=W)
        self.label8= Label(links , text="Adresse: ",bg="#000000",fg="#FF0000").pack(anchor=W)
        self.text8= Label(links , text=profil[7],bg="#000000",fg="#FF0000").pack(anchor=W)
        self.label9= Label(links , text="Stadt: ",bg="#000000",fg="#FF0000").pack(anchor=W)
        self.text9= Label(links , text=profil[8],bg="#000000",fg="#FF0000").pack(anchor=W)
        self.label10= Label(links, text="Kreis: ",bg="#000000",fg="#FF0000").pack(anchor=W)
        self.text10= Label(links , text=profil[9],bg="#000000",fg="#FF0000").pack(anchor=W)
        self.label11= Label(rechts , text="Telefonnr: ",bg="#000000",fg="#FF0000").pack(anchor=W)
        self.text11= Label(rechts , text=profil[10],bg="#000000",fg="#FF0000").pack(anchor=W)
        self.label12= Label(rechts , text="FAX: ",bg="#000000",fg="#FF0000").pack(anchor=W)
        self.text12= Label(rechts , text=profil[11],bg="#000000",fg="#FF0000").pack(anchor=W)

        self.label6= Label(links , text="Interessen: ",bg="#000000",fg="#FF0000").pack(anchor=W)
        self.interessen = Text (links,height="5",bg="#020202",fg="#FF0000")
        self.interessen.pack()
        self.interessen.insert(END,profil[5])
        
        # Verhindern das die Ausgabe manipulierbar ist
        self.interessen.unbind_class("Text", "<Return>")
        self.interessen.unbind_class("Text", "<Any-KeyPress>")
        self.interessen.unbind_class("Text", "<Any-KeyRelease>")
        
    
        
                
        
        

        self.mainloop() #ENDE Profil

Ok es liegt am mainloop aber dann hab ich das problem , dass das Ava nichtmehr angezeigt wird sondern nurnoch ein weisser kasten... wie kann ich dass dann beheben?
BlackJack

@KillingTears: Ganz am Ende startest Du eine zweite Hauptschleife. Wie der Name vielleicht vermuten lässt, sollte es davon nur *eine* geben. Der Aufruf kehrt erst zurück, wenn das Programm beendet wird.

Ansonsten sollte man keine Werte selber in SQL-Anfragen per Zeichenkettenformatierung oder durch "zusammenbauen" einfügen, sondern das immer dem Datenbankmodul überlassen. Siehe [wiki]Parametrisierte SQL-Queries[/wiki]

Ein paar Zeilenumbrüche in dem SQL wären auch nett, damit die Zeilen bei einer vernünftigen Länge bleiben.

Du setzt Leerzeichen ziemlich inkonsequent ein.

Pfade und Dateinamen setzt man plattformunabhängig mit `os.path.join()` zusammen.

Auf das Avatarbild musst Du auf Pythonseite eine Referenz behalten, sonst schlägt die Speicherbereinigung zu und löscht die Bilddaten und Tk hat nichts mehr zum Anzeigen. Das funktioniert jetzt nur, weil die Funktion wegen der Hauptschleife am Ende nicht verlassen wird bevor das Programm beendet wird, und deshalb auch bis zum Ende die lokalen Namen existieren.

Brauchst Du wirklich alles was Du an das Objekt bindest dort auch? Und durchnummerieren von Namen ist oft ein Hinweis auf ein Entwurfsproblem.

Es ist viel sich wiederholender Quelltext, den man durch eine Schleife kürzer und übersichtlicher gestalten kann.

Das Verändern vom Inhalt von `Text`-Exemplaren kann man verhindern, wenn man die Option `state` auf `Tkinter.DISABLED` setzt, nachdem der gewünschte Text eingefügt ist. Bei Deiner Methode könnte man zum Beispiel vielleicht noch Text über die Zwischenablage in das Widget bekommen.
KillingTears
User
Beiträge: 7
Registriert: Freitag 10. April 2009, 01:45

Vielen Dank für die Hilfe soweit würde auch alles klappen bis auf das schrumpfen des Textes mit den Labeln da sagt der bei titel + ":" das instance nicht mit string verbunden werden kann .

naja und ich hab noch ein problem... eigtl Datenbanken , aber da es hiermit zusammenhängt schreib ich direkt mit :

Und zwar klappt die Suche nach einem User auf diese weise nicht. ich krieg ein Error das ' ein unerwünschtes zeichen ist aber es ist notwendig Oo.

hier mal die Syntax :

Code: Alles auswählen

from_and_where = ("FROM `jos_users` "
                          "WHERE username LIKE '%%s%'") # '%' %s '%' bringt auch nichts
       
        cursor.execute("SELECT `username` "
                       + from_and_where,
                       (suchbegriff,))
Eigentlich sollte er ja den Code annehmen , da der String in dieser Form funktioniert hatte :

"SELECT `username` FROM `jos_users` WHERE username like '%" + suchbegriff + "%';"
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Um ein `%` in einen String zu bekommen musst du ihn escapen -> `%%`.
Um per String-Formatting einen anderen String einzubinden braucht man `%s` und nach dem string ein `% NAME_TO_INSERT`.
=> Schau dir mal die Doku zu String-Formatting an.

Außerdem benutzt du in deinem String Backticks und keine einzelnen Anführungszeichen.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Einfach nur %s ohne die Anführungszeichen. Das macht die execute-Methode selber.
Das Leben ist wie ein Tennisball.
KillingTears
User
Beiträge: 7
Registriert: Freitag 10. April 2009, 01:45

das Problem ist das bei er bei mir beim '%' %s '%' meckert und wenn ich '%%' %s '%%' kommt zwar kein Error mehr aber auch kein Ergebnis .
Antworten