How to change variable in another python file? - python

I have two python files. In this example I have made it really simple, File_A and File_B. In File_A I want to define a variable, and in File_B I want to use this variable to do something.
The code is a bit more complex, but this is the idea:
FileA:
import tkinter as tk
window = tk.Tk()
entry = tk.Entry(window)
entry.pack()
button = tk.Button(window, text="Click me!", command=lambda: on_button_click(entry.get()))
button.pack()
def on_button_click(ip):
pass
#changing variable in File_B to 'ip'
#run File_B
window.mainloop()
File_B:
print(value) #value entered in File_A
I have tried things in File_B like:
From File_A import value
But this didn't seem to work for me, or it made the GUI open once more.
Does anyone have a suggestion?

You can wrap the file's code with a function instead, and pass relevant variables using the function parameters.
TestB:
def main(ip):
print(ip)
<rest of code for file TestB>
TestA:
import TestB
def on_button_click(ip):
TestB.main(ip)
Maybe add more details to your question (what are you trying to do?), there might be a more efficient way to solve this problem.

Related

Tkinter destroying an object in a different function isn't working

I'm trying to make a button that saves your username but then goes away after you set it.
this is my code:
def printValue():
User = Name.player_name.get()
label.config(text=f'Hi, {User}')
Name.button.destroy()
Name.player_name.destroy()
def Name():
label.config(text="What's your name?")
Name.player_name = Entry(root)
Name.player_name.pack(pady=15)
Name.button = Button(text="Change", command=printValue)
Name.button.pack()
The code below, with some minor changes like enabling change with [Return] and some layout cosmetics works OK (also with un-commented lines in printValue) . If you want the [Change] button and the entry area to go away un-comment the two lines turned into comments in the printValue function:
# https://stackoverflow.com/questions/72671126/tkinter-destroying-an-object-in-a-different-function-isnt-working
from tkinter import Tk, mainloop, Entry, Button, Label
root = Tk()
label = Label(root, font=('',12), padx=15, pady=5)
label.pack()
def Name():
label.config(text="What's your name?")
Name.player_name = Entry(root, font=('',12))
Name.player_name.pack(padx=15, pady=15)
Name.player_name.focus()
Name.button = Button(text="Change", command=printValue)
Name.button.pack()
def printValue(event=None):
User = Name.player_name.get()
# Name.player_name.destroy()
# Name.button.destroy()
label.config(text=f'Hi, {User}')
Name()
root.bind("<Return>", printValue)
mainloop()
By the way: The in the question provided code demonstrates an interesting approach of making names of variables global by setting function attributes in the function itself. This way it is possible to assign values in one function and retrieve them in another without passing return values or declaring variables global. I am not aware of already having seen such approach used in Python code here on stackoverflow. How does it come you use such code?

Python, Tkinter - some general questions about the code

I have some general questions regarding working code below:
tkinter is library for graphic interface as I understand I can use it interchangeably with for example Kivy?
Would it be better to learn Kivy instead or other?
Lines import tkinter as tk and from tkinter import * do exactly the same, in the first one I have alias though?
In the code below, why do I have to use ttk in ttk.Progressbar?
I imported whole library with import tkinter as tk so why do i have to reimport ttk just for progress bar? (otherwise it is not working). I would expect to work sth. like tk.Progressbar
In the line btnProg = tk.Button(self.root, text = 'update', command=self.fnUpdateProgress), why method "fnUpdateProgress" can't have any variables? Whenever I add any, the button stop working? -> for example btnProg = tk.Button(self.root, text = 'update', command=self.fnUpdateProgress(24)) (ofc then some changes in def of the method itself)
I created progress bar (pb) as attribute of the class Test, but wolud it be better to define it as regular variable (without self)? To be honest, code works exactly the same.
Code:
import tkinter as tk
from tkinter import *
from tkinter import ttk
from CreateProgramMain import main
import GlobalVariables
class Test():
####################################################################################
def __init__(self):
self.Progress=0
self.root = tk.Tk()
self.root.title(GlobalVariables.strAppName)
self.root.geometry('400x200')
lbl = Label(self.root, text="Please choose environment.",font=("Arial Bold", 12))
lbl.grid(column=2, row=0,sticky='e')
def btnTestClicked():
main("TEST",self)
btnTest=tk.Button(self.root, text="Test Environment", command=btnTestClicked)
btnTest.grid(column=2, row=15)
#Place progress bar
pb = ttk.Progressbar(self.root,orient='horizontal',mode='determinate',length=200)
pb.grid(column=1, row=65, columnspan=2, padx=10, pady=20)
pb["value"]=self.Progress
pb["maximum"]=100
btnProg = tk.Button(self.root, text = 'update', command=self.fnUpdateProgress)
btnProg.grid(column=2, row=75)
self.root.mainloop()
def fnUpdateProgress(self): #why i cant insert variable inside?
pb["value"]=self.Progress
self.Progress=self.Progress+5
pb.update()
app = Test()
Thank you
it is upto you. However, tkinter and kivy both have their own syntaxes, commands, and their own usages. It might be a little difficult to convert tkinter code to kivy.
it is upto you
Yes. In the first, you have imported tkinter as tk. In the second one. You have done a wild card import. You have imported everything
Tkinter is a folder containing various modules. It contains a file called ttk.py which you have to import to access ttk.
All other classes like Label, Entry, Tk is present in __init__.py
you have to use lambda for it. If you call the function, it will be executed wlright away and the returned value is kept as the command.
Doing command=self.fnUpdateProgress(24)) will execute the function right away. Then, the returned value is kept as a command. Here, it returns None. So the command is nothing or the button is useless.
Use a lambda expression command=lambda: self.fnUpdateProgress(24))
if you don't add self it will be local to the function only. To access ot outside, it would have to be declared global, which is the point to avoid while using classes

What are the alternatives to Globals in Python using Tkinter

I am teaching a class and have been told to avoid global statements using Python and Tkinter. I don't want to teach Classes to my students yet
I know I can create all my entry boxes and labels out of a subroutine and my code will work, but this is just teaching a different bad practice
from tkinter import *
def print_name():
print(entry_location.get())
def main():
global main_window,entry_location
main_window =Tk()
Button(main_window, text="Print Name",command=print_name) .pack()
entry_location = Entry(main_window)
entry_location.pack()
main_window.mainloop()
main()
This works with the global statement, but short of removing the code in main() from the subroutine is there an alternative?
In your example, you can eliminate globals by registering a lambda function to the button; this lambda function collects te value in the entry, and passes it as a parameter to print_name.
import tkinter as tk
def print_name(text=''): # <- now receives a value as parameter
print(text)
def main():
main_window = tk.Tk()
entry_location = tk.Entry(main_window)
tk.Button(main_window, text="Print Name", command=lambda: print_name(entry_location.get())).pack()
entry_location.pack()
main_window.mainloop()
main()
Note:
This answers the special case of your example; it is not a generic answer to eliminating globals entirely. Alternative approaches could be to place the variables needed globally in a dictionary, or a list, thus permitting their modification in the local spaces, but in the end, it might become more complicated than using a proper class.
As suggested by #AndrasDeak, it is better to avoid star imports.
as phydeaux said, you can do this py simply passing the variables as parameters.
full ammended code shown below:
from tkinter import *
def print_name(entry_location):
print(entry_location.get())
def main(main_window, entry_location):
main_window =Tk()
Button(main_window, text="Print Name",command=print_name) .pack()
entry_location = Entry(main_window)
entry_location.pack()
main_window.mainloop()
main(main_window, entry_location)

Python variable equal to class method? Syntax

so I'm starting to learn python and I need to write a script that edits a CSV file. I found this online and had a few questions about what it's exactly doing since the original programmer didn't explain. My question right now though is about syntax. I'm a little confused about some of these lines:
import Tkinter,tkFileDialog
root = Tkinter.Tk()
root.filename = tkFileDialog.askopenfilename(initialdir = "/", title =
"Select a file", filetypes = (("csv files", "*.csv"),))
So my first question is what root equals. I understand I imported two modules called Tkinter and tkFileDialog(Correct me if I'm wrong) into my file. I then created a variable called root and set it equal to a method call?
root = Tkinter.tk()
Next, what does this line do? Is filename a method in one of those modules? I read something about widgets...are widgets methods? As in the word is used interchangeably?
root.filename
Thank you in advance!
You may benefit more form some youtube tutorials on python methods/functions and classes but I can answer your questions in general terms.
So my first question is what root equals.
root is the variable name assigned to the instance that is being created with tkinter.Tk()
This allows you to interact with that instance of tkinter and you can use root to place widgets on the main window of the GUI.
Next, what does this line do? root.filename
root.filename is only a variable name. tkFileDialog.askopenfilename is the class method being used to get the file and assign the file information to the variable name root.filename
So what you are doing here is importing the library tkinter that contains many class methods that can be used to build and manipulate a GUI interface.
note that for an instance of tkinter you will need a mainloop() at the end of your code to make it work. So at the end of your code you will need to have something like root.mainloop() to make sure the program will work as long as everything else is done correctly.

How to pass a variable from one Python script to another?

I know this question is discussed in forums ad I have read about it a lot but I still dont have solution I need.
Following code is very simplified version of my real code.
My first script is following(kyssa1.py):
import os
import sys
def type():
global dictionary
dictionary="C:\Python27\Myprojects\physics.txt"
os.system("C:\Python27\Myprojects\kyssa2.py")
from Tkinter import *
t = Tk()
b = Button(t, text="Start", command = lambda:type())
b.pack(expand=Y)
t.mainloop()
And my second script (kyssa2.py) is following:
# -*- coding: utf-8 -*-
from kyssa1 import dictionary
def open():
global dictionary
global lines
global datafile
datafile = file(dictionary)
lines = [line.decode('utf-8').strip() for line in datafile.readlines()]
for i in lines:
text.insert(END, i)
open()
from Tkinter import *
root = Tk()
text = Text(root,font=("Purisa",12))
text.pack()
root.mainloop()
What I want to do is to open file physics.txt in kyssa2.py and execute command in function open() with this text, but it doesn't wor the way I want to. What happens when I click "Start" button is another window just like defined in "kyssa1.py" appears. How could I just pass variable dictionary from one script to another?
In kyssa1.py declare dictionary in module scope, i.e.outside of the type() function.
You don't need to use global in kyssa2.py, you can refer directly to dictionary.
Also, to open the file, use open() rather than file():
datafile = open(dictionary)

Categories

Resources