Domanda

Giocare con Python - tkInter - Widget di immissione - quando uso validatecommand (sotto), il controllo avviene la prima volta che la stringa > Max, ma quando continuo a inserire il testo i passaggi di controllo - non ci sono cancellazioni o inserimenti dopo la prima volta? Qualche consiglio? (oltre a non creare un'app desktop tramite Python)


#!/usr/bin/env python
from Tkinter import *

class MyEntry(Entry):

    def __init__(self, master, maxchars):
        Entry.__init__(self, master, validate = "key",    validatecommand=self.validatecommand)
        self.MAX = maxchars

    def validatecommand(self, *args):
        if len(self.get()) >= self.MAX:
            self.delete(0,3)
            self.insert(0, "no")
        return True

if __name__ == '__main__':
    tkmain = Tk()
    e = MyEntry(tkmain, 5)
    e.grid()
    tkmain.mainloop()
È stato utile?

Soluzione

Dall'uomo Tk :

  

L'opzione validate si imposterà anche su none quando si modifica il widget di voce all'interno di validateCommand o invalidCommand. Tali edizioni avranno la precedenza su quella in corso di convalida. Se si desidera modificare il widget di immissione (ad esempio impostarlo su {}) durante la convalida e avere ancora l'opzione di convalida impostata, è necessario includere il comando

     

dopo inattività {% W config -validate% v}

non so come tradurlo in python.

Altri suggerimenti

Ecco un esempio di codice che limiterà l'input a 5 caratteri:

import Tkinter as tk

master = tk.Tk()

def callback():
    print e.get()

def val(i):
    print "validating"
    print i

    if int(i) > 4:
        print "False"
        return False
    return True

vcmd = (master.register(val), '%i')

e = tk.Entry(master, validate="key", validatecommand=vcmd)
e.pack()

b = tk.Button(master, text="OK", command=lambda: callback())
b.pack()

tk.mainloop()

Ho inserito un sacco di dichiarazioni stampate in modo da poter vedere cosa sta facendo nella console.

Ecco le altre sostituzioni che puoi passare:

   %d   Type of action: 1 for insert, 0  for  delete,  or  -1  for  focus,
        forced or textvariable validation.

   %i   Index of char string to be inserted/deleted, if any, otherwise -1.

   %P   The value of the entry if the edit is allowed.  If you are config-
        uring  the  entry  widget to have a new textvariable, this will be
        the value of that textvariable.

   %s   The current value of entry prior to editing.

   %S   The text string being inserted/deleted, if any, {} otherwise.

   %v   The type of validation currently set.

   %V   The type of validation that triggered the callback (key,  focusin,
        focusout, forced).

   %W   The name of the entry widget.

Sono sicuro di quale sia il motivo, ma ho un sospetto. Il controllo di convalida viene eseguito ogni volta che la voce viene modificata. Ho fatto alcuni test e ho scoperto che effettivamente viene eseguito e che può fare ogni sorta di cose durante la convalida ogni volta. Ciò che fa sì che smetta di funzionare correttamente è quando lo si modifica dalla funzione validatecommand. Ciò causa l'ulteriore arresto della chiamata della funzione di convalida. Immagino che non riconosca più ulteriori modifiche al valore della voce o qualcosa del genere.

lgal Serban sembra avere le informazioni dietro le quinte sul perché ciò avvenga.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top