0

As i have set search term to global for the first function - shouldnt the second function be able to access it - if not how would i get this to work?

import sys
import os.path
from tkinter import *
import math

def setupsearch():
    exist = os.path.isfile('messages.txt')
    if exist == True:
        global searchterm
        gui2 = Toplevel(master=gui)
        Label(gui2, text = "Search Term").grid(row = 0)
        searchterm = Entry(gui2).grid(row = 1)
        Button(gui2, text="Search", command = search).grid(row = 2)
    else:
        labelprint = "No Stored Messages"
        add = Label(gui, text = labelprint, width = 30)
        add.grid(row = 2, column =2)

def search():
    searchterm = 
    with open('messages.txt', 'r') as inF:
        i = 1
        for line in inF:
            if searchterm in line:
                print("found it in line " + str(i))
                i = i + 1
            else:
                print("Not in line " + str(i))
                i = i + 1  

gui = Tk()

Button(gui, text="Retriever", command=setupsearch).grid(row = 5, column = 0)

mainloop( )
A..
  • 375
  • 2
  • 6
  • 15
  • Note that `searchterm` is not what you think, if you place a debugging `print(searchterm)` in your code you'll see with your eyes. – gboffi Nov 10 '14 at 00:02
  • Further, the other answer are good solutions for your question about global variable, but not as good with respect to your problem, that is different from what you assume. Summary, (1) in callbacks use `lambda: f(x)` to pass around your values, (2) `Tkinter.Entry()` returns a widget, not the value of the text. – gboffi Nov 10 '14 at 00:10

3 Answers3

1

Each function that wants to change the value of the searchterm global variable needs to declare global searchterm. The global statement doesn't change properties of the variable itself—rather, it changes properties of the function, specifically the way the current function sets and gets values for the variable name in question.

You can get away with accessing a global variable from inside a function, without declaring it global, provided (a) there is no local variable of the same name to conflict with it, and (b) you don't need to change its global value.

If you don't say global searchterm but then assign something to searchterm, the function will simply create a local variable of that name.

jez
  • 14,867
  • 5
  • 37
  • 64
  • @zaxvo When i change it to global searchterm in search() function it returns the "TypeError: 'in ' requires string as left operand, not NoneType" – A.. Nov 09 '14 at 21:04
1

In your setupsearch use

        Button(gui2,
               text="Search",
               command = lambda: search(thesearchterm)).grid(row = 2)

and of course modify the definition of search

def search(searchterm):
    ...

Note that I used lambda: search(the_searchterm) for a good reason, as searchterm = Entry(...) is a widget. Please read a tutorial on Tkinter.Entry or simply, from the shell prompt, use man Entry (you must have installed the docs for tk, of course).

gboffi
  • 22,939
  • 8
  • 54
  • 85
0

You want to begin your second function by stating:

def search():
    global searchterm
    ## rest of function goes here

Then you'll be able to access the global variable from within search()

With that being said...I'm sure you know that, in general, having global variables is a bad idea.

zaxvo
  • 186
  • 1
  • 10
  • why is having global variables is a bad idea. – A.. Nov 09 '14 at 21:00
  • 2
    @MatthewStevens-Keane - The advice given here applies to almost all languages, including Python: http://stackoverflow.com/a/10525602/2555451 –  Nov 09 '14 at 21:04
  • When i change it to global searchterm in search() function it returns "TypeError: 'in ' requires string as left operand, not NoneType" – A.. Nov 09 '14 at 21:06
  • 1
    Because then any function anywhere in your program could affect that variable. This might be what you want, but in general it's bad practice. (Of course, there are exceptions to the rule) In your case I would have the first line in `search()` be a read of the search term from the UI field. Avoids the global variable and makes the structure more obvious. I'm unfamiliar with Tkinter lib, but [my best guess is] it would be something like `searchterm = Entry(gui.gui2).grid(row=1)` so it's clear where you're getting that value from. – zaxvo Nov 09 '14 at 21:07
  • @zaxvo how would i get the first line in search() to be a read of the search term from the UI field. – A.. Nov 09 '14 at 21:09