entry.focus_set()

Fragen zu Tkinter.
Antworten
Nobuddy
User
Beiträge: 994
Registriert: Montag 30. Januar 2012, 16:38

Hallo zusammen,

habe das Problem, daß ich den Focus nicht in das gewünschte Entry-Feld bekomme.
Poste mal hier, die Gui um die es geht.
Sie funktioniert, bis auf das Focus-Feld.

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# For Python3.x

import tkinter as tk
import tkinter.messagebox


"""Programmname"""
PROGRAMMNAME = 'gui_test.py'


class TabelleWork(object):
    """
    Listbox mit Scrollmenü.
    Tabellarische Ausgabe der Daten in Spalten.
    Tabellenausgabe, mit automatischer Anpassung an die Spaltenanzahl
    der jeweiligen Liste.

    Aufruf:
    Controller(LISTE, LISTE_FÜR_SPALTENBENENNUNG, MAXIMALE_SPALTENWEITE,
        FOCUS, COLOR).run()

    LISTE = Liste wie z.B. ['4711', 'Schraube', '2.25']
    LISTE_FÜR_SPALTENBENENNUNG = Liste wie z.B. ['Artikel', 'Benennung', 'Vk']
    MAXIMALE_SPALTENWEITE = Liste wie z.B. [10, 60, 4]
    FOCUS = Int-Wert, wie z.B. 2, Focus in zweite Spalte setzen
    COLOR = Farbe des Button-Frames
    """
    

    def __init__(self, controller, result, name, max_width, focus, color):

        self.my_win = tk.Toplevel()

        # Layout Definition
        self.txt2 = ('NimbusSansL', '14')
        self.fcdg = 'darkgrey'
        self.bg = 'grey'

        self.controller = controller
        self.result = result
        self.label_names = name
        self.max_width = max_width
        self.focus = focus
        self.color = color

        self.frame = tk.Frame(self.my_win, bg='#822')
        self.frame.pack(side='top', expand=False)
        self.winLabel = tk.Label(self.frame)
        self.winLabel.pack(expand=False)

        if len(self.result) == 0:
            return self.controller.close()


    def set_scrolled_tables(self):
 
        self.max_label = round(max([len(x) for x in self.label_names]
            ) * 1.3)
        self.max_item = round(max([len(str(x)) for x in self.result]) * 1.3)
        if self.max_item < 50:
            self.max_item = 50

        self.zeilen = len(self.label_names)
        if self.zeilen == 0:
            return self.controller.close()

        # Ermittle die Zeilen- und Gesamthöhe
        zeilencheck = {14 : 32, 13 : 44, 12 : 42, 11 : 40, 10 : 36,
            9 : 34, 8 : 33}
        h_now = self.zeilen * zeilencheck.get(int(self.txt2[1]))
        self.h_max = round((self.my_win.winfo_screenheight() - 120))
        if int(h_now) < int(self.h_max):
            self.h_max = h_now

        if self.color != '':
            self.tabellenWindow = tk.Frame(self.winLabel, bg=self.color)
        else:
            self.tabellenWindow = tk.Frame(self.winLabel)
        self.tabellenWindow.grid(row=0, column=0, sticky=tk.NSEW)
        self.tabellenWindow.grid_rowconfigure(0, weight=1)
        self.tabellenWindow.grid_columnconfigure(0, weight=1)

        # Buttons erstellen
        mybutton = (('Übernehmen', self.controller.take),
            ('Schließen', self.controller.close))
        self.len_max = (max([len(row[0])
            for row in mybutton]))
        self.button_frame = tk.Label(self.tabellenWindow, bg=self.fcdg)
        self.button_frame.grid(row=1, column=0)
        for i, row in enumerate(mybutton):
            tk.Button(self.button_frame, bg=self.bg, width=self.len_max,
                font=self.txt2, text=row[0], command=row[1]
                ).grid(row=0, column=i)

        self.canvas = tk.Canvas(self.tabellenWindow, bd=0)
        self.canvas.grid(row=0, column=0, sticky=tk.NSEW)

        self.canvas1 = tk.Canvas(self.canvas, bd=0, width=self.max_label)
        self.canvas1.grid(row=0, column=0, sticky=tk.NSEW)

        self.canvas2 = tk.Canvas(self.canvas, bd=0, width=self.max_item)
        self.canvas2.grid(row=0, column=1, sticky=tk.NSEW)

        self.entry_ipadx = 5 # Abstand zu Text in x
        self.entry_ipady = 2 # Abstand zu Text in y

        self.set_scrolled_entries()

        self.ypos = self.h_max
        self.canvas.update_idletasks()

    def set_scrolled_entries(self):
        """Tabellenspalte erstellen"""

        self.ypos = 0
        data = list()
        self.entry_vars = list()
        for i, name in enumerate(self.label_names):
            var = tk.StringVar()
            self.xpos = 0
            label = tk.Label(self.canvas1, width=self.max_label,
                text=name, font=self.txt2, bg=self.bg, fg='brown', bd=1,
                highlightthickness=1, anchor=tk.W)
            label.grid(row=i, column=0, padx=self.entry_ipadx,
                pady=self.entry_ipady)
            self.xpos += label.winfo_reqwidth()
            entry = tk.Entry(self.canvas2, width=self.max_item,
                textvariable=var, font=(self.txt2), bg=self.bg, bd=1,
                highlightthickness=1)
            entry.grid(row=i, column=0, padx=self.entry_ipadx,
                pady=self.entry_ipady)
            if i == self.focus:
                print('Setze Focus')
                entry.focus_set()
            try:
                var.set(self.result[i])
            except IndexError:
                var.set('')
            data.append(var)
            self.entry_vars.append(var)
            self.xpos += entry.winfo_reqwidth()


    def run(self):
        self.my_win.update()
        self.set_scrolled_tables()
        # Zentriere das Fenster auf dem Bildschirm
        x, y, hdw, hdh = (self.xpos + 25, self.ypos + 50, self.xpos, self.ypos)
        self.my_win.geometry('{}x{}+{}+{}'.format(x, y, hdw, hdh))
        self.my_win.mainloop()


class Controller(object):

    def __init__(self, result, name, max_width, focus, color):

        self.model = Model(result, name, max_width, focus, color)
        self.view = TabelleWork(self, self.model.result, self.model.name,
            self.model.max_width, self.model.focus, self.model.color)
    
    def take(self):
        self.datacheck = True
        self.view.my_win.quit()
        return self.view.my_win.destroy()

    def close(self):
        self.datacheck = False
        self.view.my_win.quit()
        self.view.my_win.destroy()
        return None

    def get_data(self):
        # Übergebe die veränderten und unveränderten Daten zum verarbeiten
        workline = [entry_var.get() for entry_var in self.view.entry_vars]
        mylist = list()
        for i, row in enumerate(workline):
            mylist.append(row.upper())
        print('mylist', mylist)
        return mylist

    def run(self):
        self.view.run()
        try:
            if self.datacheck:
                return self.get_data()
        except AttributeError:
            pass


class Model(object):

    def __init__(self, result, name, max_width, focus, color):
        self.result = result
        self.name = name
        self.max_width = max_width
        self.focus = focus
        self.color = color


def main():
    result = ['2014.05.18', '', 'Kunde 4711', '49.90']
    name = ['Datum', 'Rechnung', 'Kunde', 'Betrag', 'Erhalten',
        'Eingang', 'Zahlort']
    max_width = [20, 20, 20, 30]
    focus = 4
    color = 'red'
    error = ''
    Controller(result, name, max_width, focus, color).run()


if __name__ == '__main__':
    main()
Was mache ich falsch, daß dies nicht funktioniert.
Nobuddy
User
Beiträge: 994
Registriert: Montag 30. Januar 2012, 16:38

Ich habe festgestellt, daß der Curser auf die ausgewählte Tabellenzeile spring, wenn ich außerhalb der Tabelle auf den Rahmen klicke.
Wie bekomme ich das hin, das dies automatisch geht?
Nobuddy
User
Beiträge: 994
Registriert: Montag 30. Januar 2012, 16:38

Habe die Ursache herausgefunden.
Ich habe die Gui zum Testen immer direkt gestartet, mit 'self.my_win = tk.Toplevel()', was zu dem genannten Problem führt.
Verwende ich statt dessen 'self.my_win = tk.Tk()', funktioniert das mit dem focus_set(). :)
Antworten