troubles mit radiobuttons

Fragen zu Tkinter.
Antworten
Gast

Dienstag 29. März 2005, 02:39

hallo zusammen,

ich habe folgendes problem: nachstehender code ist teil einer größeren anwendung, es geht um gui und datenbank, habe da mal zur übung einiges ausprobiert. ursrprünglich gab es eine klasse Fenster, von der grundlegende attribute und methoden alle anderen fenster, wie HauptFenster, EingabeFenster und eben auch SuchFenster, PasswortFenster usw. usw. geerbt haben.

Nun zum eigentlichen Problem: Wie man unschwer erkennen kann gibt es hier eine methode, die nur mal zu Testzwecken so geschrieben wurde (get_selected): ausgebeben werden soll der jeweilige wert der StringVar() self.choice. Starte ich das SuchFenster für sich allein, klappt auch alles, wird aber SF z. B. über das HauptFenster (für Datenausgabe, usw) aufgerufen, wird None zurückgegeben, also nichts.

In der Zwischenzeit habe ich die Suchoption im HF eingebaut und es funzt tadellos, dennoch will ich wissen, verstehen, warum das nicht geht, oder nur halb.

Mal zum Code:

Code: Alles auswählen

class SuchFenster(Fenster):


    def __init__(self,lt,r):

        Fenster.__init__(self,lt,r)
         
        self.root.title("Suchfenster")

        self.choice=StringVar()

        # Normalerweise wird self.database vom HauptFenster übergeben, 
        # da dort schon eine Instanz aufgerufen wird.
        self.database=DataBase('localhost','irgendwer','einedatenbank','einetabelle','ein....') 
        
        self.cols_names=[]

         # Spaltennamen, der aktuellen Tabelle werden ermittelt

        for elements in self.database.db_table_cols:

             self.cols_names.append(elements[0])        

        self.entry=Entry(self.root)
        self.entry.grid(row=3,column=0)
        
        #entsprechend den ermittelten Namen wird das SF dynamisch aufgebaut

      
        for i in range(len(self.cols_names)): 
            self.rb=Radiobutton(self.root,text=self.cols_names[i],
                        value=self.cols_names[i],
                        variable=self.choice)
            self.rb.grid(row=i+2,column=1,padx=self.a_x,pady=self.a_y)

            

        self.b_1=Button(self.root,text="Suche",command=self.get_selected)
        self.b_1.grid(row=i+1,column=0)
        
        self.root.mainloop()


    def get_selected(self):
        choice=self.choice.get()
        print choice
        # Funktion zum Testen was ausgegeben wird. 
        # Wie oben beschrieben Ergebnis nur, wenn es alleine verwendet wird.




vielen dank im voraus

rolgal
Gast

Dienstag 29. März 2005, 12:48

also, ich habe mal schnell was geschustert, das die oben beschriebene problematik ausführen lässt

Code: Alles auswählen

#!/usr/bin/python
# -*- coding: cp1252 -*-

import sys
from Tkinter import *

class HauptFenster:

    def __init__(self):
        self.root=Tk()
        self.b_1=Button(self.root,text="Suchen",command=SuchFenster)
        self.b_1.pack()
        self.b_2=Button(self.root,text="Ende",command=lambda:sys.exit(0))
        self.b_2.pack()
        self.root.mainloop()
    



class SuchFenster:


    def __init__(self):

        self.root=Tk()
         
        self.root.title("Suchfenster")

        self.choice=StringVar()

        # Normalerweise wird self.database vom HauptFenster übergeben,
        # da dort schon eine Instanz aufgerufen wird.
##        self.database=DataBase('localhost','irgendwer','einedatenbank','einetabelle','ein....')
       
        self.cols_names=["id","name","vorname","land"] #Spaltennamen werden normalerweise ermittelt

         # Spaltennamen, der aktuellen Tabelle werden ermittelt
##
##        for elements in self.database.db_table_cols:
##
##             self.cols_names.append(elements[0])       

        self.entry=Entry(self.root)
        self.entry.grid(row=3,column=0)
       
        #entsprechend den ermittelten Namen wird das SF dynamisch aufgebaut

     
        for i in range(len(self.cols_names)):
            self.rb=Radiobutton(self.root,text=self.cols_names[i],
                        value=self.cols_names[i],
                        variable=self.choice)
            self.rb.grid(row=i+2,column=1)

           

        self.b_1=Button(self.root,text="Suche",command=self.get_selected)
        self.b_1.grid(row=i+1,column=0)
       
        self.root.mainloop()


    def get_selected(self):
        choice=self.choice.get()
        print choice
        # Funktion zum Testen was ausgegeben wird.
        # Wie oben beschrieben Ergebnis nur, wenn es alleine verwendet wird.

        
if __name__=="__main__":

    hf=HauptFenster()
normalerweise erben HF und SF ne menge von F, habe ich jetzt aber rausgenommen, und auch sonst einiges auskommentiert...

startet mal wie oben angeführt, drückt im HF "Suchen" und nichts wird zurückgegeben

startet statt hf=HauptFenster(), sf=SuchFenster() und es funktioniert.

dachte es ist vielleicht sinnvoll, das so nochmal reinzustellen,

mfg

rolgal
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

Dienstag 29. März 2005, 13:46

Hi

Danke für die 2. Ausführung, ohne die war es gar nicht möglich den Fehler zu finden :).

Also du darfst nicht zweimal root = Tk() aufrufen, nur einmal (Hauptfenster). Wenn du ein 2. Fenster willst musst du Toplevel(root) nehmen.

Code: Alles auswählen

class HauptFenster:
    def __init__(self):
        self.root=Tk()
        self.b_1=Button(self.root,text="Suchen",command=lambda: SuchFenster(self.root))
        ...

class SuchFenster:
    def __init__(self,root):
        self.root=Toplevel(root)
        ...

if __name__=="__main__":
    hf = HauptFenster()

So funktionierts (hab nur änderungen im Code nochmals gepostet).
1. Änderung beim Command beim Button.
2. Änderung beim initialisieren von Suchfenster.

Gruss Rayo
Gast

Dienstag 29. März 2005, 13:55

hi rayo,

ansich alles klar jetzt, werde das bald ausprobieren.
normalerweise wird ja

Code: Alles auswählen

self.root=Tk()
vererbt von Fenster, im orig. wird ja auch der konstuktor von Fenster ausgeführt.
das heisst bei lambda kommt es weg und stattdessen überschreiben, wie du es im code gezeigt hast, dann müsste es klappen.



danke für deine mühe,

rolgal

Nachtrag: ganz so wie ich es oben beschrieben habe ist es nicht, aber so ähnlich, aber auf jeden Fall viel zu aufwendig es ganz genau zu erklären, :D , root muss aber im aufruf nach lambda sehr wohl übergeben werden
Antworten