1

I have created around 5 Entry boxes and binded them as well. Take this as model:

def makeEntry(self, master, data):
    self.entry = Entry(master, width=8, textvariable=data)
    self.entry.bind("<Leave>", lambda event, value=data: self.validate(event, value))

Now, I did also a validate method that check if the input was a string (and if so, the highlight background of the entry would change to red). The problem which is still taking me a lot of time is that I would need that the method should be able to check every entries, and if at least one of them has got a red background, then a final button should be disabled (button.configure(state=DISABLED)).

With just one entry it would be much easier, I would simply check if the background was red (status = str(self.myOneEntry.cget("highlightbackground"))), but what about with more entries?

Cœur
  • 37,241
  • 25
  • 195
  • 267
  • 1
    Are you aware the entry widget has a built-in validation feature that doesn't require the use of bindings? – Bryan Oakley Oct 09 '15 at 14:37
  • Your question is a bit unclear. Do you want a single function that works with each entry, or do you want the single function to validate all of the entries at the same time? – Bryan Oakley Oct 09 '15 at 14:37
  • @Bryan Oakley, yes, I know it, even though I haven't used it yet. I know it is actually a bit unclear, but this is because of the fact I don't manage to implement it. Anyway, I tried to do a single function to validate all entries (which worked, but I used different names for various entries and did some controls, without using the above _makeEntry_), how can do that (second choice) with _makeEntry_ ? –  Oct 09 '15 at 15:29
  • @BryanOakley Where can the documentation be found for built-in validation? – Noctis Skytower Oct 09 '15 at 15:34
  • @NoctisSkytower: it unfortunately isn't very well documented. I wrote up a working example in [this answer](http://stackoverflow.com/a/4140988/7432). [New Mexico Tech](http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/entry-validation.html) has a short tutorial, and [effbot](http://effbot.org/zone/tkinter-entry-validate.htm) also has a brief description. – Bryan Oakley Oct 09 '15 at 16:05

1 Answers1

0

If you want to check all of your entries, keep them in a list. Then, write a function that iterates over the list and sets the button state to disabled if any widget has a red background. You can then call this whenever something changes, such as within your validation function for each widget.

Example:

class Example(...):
    def __init__(...):
        self.entries = []
        for data in ("one","two","three"):
            entry = makeEntry(...)
            self.entries.append(entry)

    def _update_button(self):
        for entry in self.entries:
            if entry.cget("background") == "red":
                self.button.configure(state="disabled")
                return
        self.button.configure(state="normal")

Note: you'll need to make sure that makeEntry(...) returns a reference to the created widget.

Also, you don't have to use makeEntry. You can create your widgets however you want. The point is to save references to the widgets in a data structure that you can iterate over. It doesn't matter how the widgets are created.

Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
  • Is still this solution good if the header of _makeEntry_ would be like `def makeEntry(self, master, data, i, field, x, y, x1, y1):` ? –  Oct 09 '15 at 18:56
  • as long as `makeEntry` returns a reference to the entry widget, it will work no matter what the arguments are. – Bryan Oakley Oct 09 '15 at 19:19
  • Sorry, but the first cycle does not convince me. If I declared `self.value1 = StringVar()` and one of the entry I should have is like `entry = makeEntry(master, self.value1, 0, " Test ", 10, 300, 90, 300)` and almost all args change for each entry, is still `entry = makeEntry(...)` right ? I might get lost... –  Oct 09 '15 at 19:39
  • @tonifrighez: I think you are focusing on the wrong problem. No matter how you create the widgets, the above technique works. Remove the call to `makeEntry` altogether and replace it with anything else. The point is, save references to your widgets in a list, and iterate over the list. It does not matter at all how you create those widgets. Create them all with one function, create them with several functions, with zero arguments, a hundred arguments, it doesn't matter. – Bryan Oakley Oct 09 '15 at 19:44
  • Yes, then I miss what you mean for saving a reference to the widget... Isn't a list passed by value in Python? I mean, should I do a kinda copy of the list? –  Oct 09 '15 at 19:52
  • @tonifrighez: the list in my example is an attribute of a class. No need to make a copy, and no need to pass it around. And no, lists are not passed by value in Python. They are passed by reference. – Bryan Oakley Oct 09 '15 at 20:17