My project said to "Implement the class for the display of the amplitude of the wave file or frequency entered and create the method that will extract a portion of the waveform to display." I am having trouble passing the user input from one file to another without importing the entire file (tried that gave me errors)
Here's some of my main file:
import tkinter as tk
import winsound
from tkinter import *
from tkinter import messagebox
from tkinter import filedialog``
from tkinter import simpledialog
import Create_Account
import Login_file
import Display_Waveform_Amplitude
class audioFrequencyGUI:
#...... (skipping unimportant code)
def Play(self, Hz):
self.play_frequency.config(command = lambda: winsound.Beep(Hz, 500))
#MAIN LOOP
tk.mainloop()
def Display_Waveform(self):
DisplayWindow = Display_Waveform_Amplitude.Display_Waveform_AmplitudeGUI()
DisplayWindow.amplitude_window.wait_window()
Heres Display Waveform File:
import tkinter as tk
from tkinter import*
import numpy as np
import matplotlib.pyplot as plt
class Display_Waveform_AmplitudeGUI:
def __init__(math):
math.amplitude_window = tk.Tk()
math.amplitude_window.title("Amplitude Display")
math.amplitude_window.minsize(width = 500, height = 500)
def plot_graph(math):
time = 1/frequency
x = np.arrange(0, time, 0.1)
y = frequency - 1
plt.title('Amplitude Waveform: Entering Frequencies')
plt.xlabel('Time (seconds)')
plt.ylabel('Amplitude')
plt.plot(x, y)
plt.show()
I know in my code I haven't passed anything because I simply don't know what to do. I've been moving things around and trying out different things for days. I just need to know how to pass the frequency from my main file to another file that contains another class and function. Thank you I appreciate the help!
If files are in same folder
I think you can solve this just importing the class in the main.py file into display file:
from main import audioFrequencyGUI
Now you can use funcs from main.py file inside display.py
Related
I recently started working on a program in python using Tkinter and now I want to open it from another file.
I have a home page file named HomePage.py that will have a button to open another file, called VirusTotalAPI.py. I didn't find any answers because when I run the program, it opens the VirusTotalAPI.py file, and if I close it the Homepage.py will run, but the button won't work and if I try to close it, it will open the HomePage.py.
#Homepage.py
from tkinter import *
import VirusTotalAPI as vt
Home_Window=Tk()
Home_Window.geometry("980x530")
Home_Window.title("VirusTotal By Carotide")
Home_Window.config(background="grey")
def Window_35_mo() :
vt.Window_35mo
Window_35_mo_open = Button()
Window_35_mo_open.config(text= "Fichier < 35 mo", command= Window_35_mo)
Window_35_mo_open.pack()
Home_Window.mainloop()
The next one is a part from the VirusTotalAPI.py because the file is too long
#VirusTotalAPI.py
import requests
import hashlib
import json
from tkinter import *
from tkinter import filedialog
import HomePage
Window_35mo = Tk()
Window_35mo.geometry("980x530")
Window_35mo.title("VirusTotal By Carotide")
Window_35mo.config(background="grey")
global files
global file_path
def retrieve_API():
API_Value=GetAPIBox.get("1.0","end-1c")
print(API_Value)
GetAPIBox=Text(Window_35mo, height=2, width=10)
GetAPIBox.pack()
API_Button=Button(Window_35mo, height=1, width=10, text="YourAPI",
command=lambda: retrieve_API())
API_Button.pack()
Window_35mo.mainloop()
Thank you in advance.
I tried to import it by different ways like this:
import VirusTotalAPI
Or this:
from VirusTotalAPI import *
I tried to do this too:
from tkinter import *
from VirusTotalAPI import Window_35mo
Home_Window=Tk()
Home_Window.geometry("980x530")
Home_Window.title("VirusTotal By Carotide")
Home_Window.config(background="grey")
#homepage
def winopen35mo() :
Window_35mo
Window_35_mo_open = Button()
Window_35_mo_open.config(text= "Fichier < 35 mo", command= winopen35mo)
Window_35_mo_open.pack()
Home_Window.mainloop()
And it told me this:
ImportError: cannot import name 'Window_35mo' from partially initialized module 'VirusTotalAPI' (most likely due to a circular import)
I finally found how to do it there is the solution :
First we need to import os, subprocess and sys
from tkinter import *
import os
import subprocess
import sys
Then,we declare the file path of the file, for this one it is VirusTotalAPI.py by doing so :
GUI_VirusTotalAPI_Path = 'C:\\Users\\...\\VirusTotalAPI.py'
Now we enter the args, to execute and enter the path name :
args = '"%s" "%s" "%s"' % (sys.executable,
GUI_VirusTotalAPI_Path,
os.path.basename(VirusTotalAPI))
We are almost there, now we create a function to run this using the args we previoulsy used :
def Open_GUI_VirusTotalAPI_35mo() :
proc = subprocess.run(args)
Then another function to destroy the window :
def DestroyHomeWindow() :
Home_Window.destroy
Finally we create the button and "tell" it to execute the command Open_GUI_VirusTotalAPI_35moand at the same time close the window :
Window_35_mo_open = Button()
Window_35_mo_open.config(text= "Fichier < 35 mo", command= lambda:[Home_Window.destroy(),Open_GUI_VirusTotalAPI_35mo()])
Window_35_mo_open.pack()
And this is how I did it, sorry for the poor explanation and my bad english, hope this helped some people.
I have a main file, with a Tkinter graphic form (the classic window), called for example A.py and main=Tk(). Also how can I recall the B.py file if it is in a subfolder of the main project?
By clicking, for example, on an item in the bar menu such as "Open form B", how can I open the graphic form (classic window) of the `B.py? IMPORTANT: without the output console, but only the graphic form
P.S: if please don't use "self". thanks
FILE A.PY: MAIN
from tkinter import *
from tkinter import ttk
import tkinter as tk
main=Tk()
main.title("xxxxxx")
main.geometry("750x750")
main.configure(bg='#282828')
#Bar Menù (no need to write all the code of bar menu)
filemenu.add_command (label = 'Open form B', command = ????)
FILE B.PY: SECONDARY
from tkinter import *
from tkinter import ttk
import tkinter as tk
secondary=Tk()
secondary.title("yyyyyyy")
secondary.geometry("750x750")
secondary.configure(bg='#282828')
EDIT (code updated, but i don't know if that's correct):
FILE A.PY: MAIN
from tkinter import *
from tkinter import ttk
import tkinter as tk
from b import *
main=Tk()
main.title("xxxxxx")
main.geometry("750x750")
main.configure(bg='#282828')
#Bar Menù (no need to write all the code of bar menu)
filemenu.add_command (label = 'Open form B', command = b.draw_graph)
FILE B.PY: SECONDARY
from tkinter import *
from tkinter import ttk
import tkinter as tk
from b import *
def draw_graph():
secondary=Toplevel("home/mypc/Destkop/Folder1/Folder2/B.py/secondary)
secondary.title("yyyyyyy")
secondary.geometry("750x750")
secondary.configure(bg='#282828')
UPLOAD 2 (only B.py):
from tkinter import *
from tkinter import ttk
import tkinter as tk
def draw_graph():
global secondary=Toplevel()
secondary.title("yyyyyyy")
secondary.geometry("750x750")
secondary.configure(bg='#282828')
#combobox
comboboxx=["xxxxxx", "xxxxx"]
combobox=ttk.Combobox(secondary, width=19)
combobox.place(x=6, y=12)
combobox.config(values=comboboxx)
combobox.set("Scegli")
# I only wrote a small part of the code, showing the combobox.
# But the code is very long. I would not like to put everything
# in the function (if that is possible)
Error: combobox=ttk.Combobox(secondary, width=19)
NameError: name 'secondary' is not defined
Code in b.py you should keep in functions to control when to run it
b.py
import tkinter as tk # PEP8: `import *` is not preferred
# in file `b.py` you don't need `import b` nor `from b import *`
def draw_graph():
win = tk.Toplevel()
label = tk.Label(win, text="GRAPH")
label.pack()
and then you can import b and assing command=b.draw_graph
main.py
(I use Button to create minimal working code - so everyone can simply copy and run it)
import tkinter as tk # PEP8: `import *` is not preferred
import b # PEP8: `import *` is not preferred
def main():
root = tk.Tk() # PEP8: spaces around `=` when assigning to variable
# ... code ...
#filemenu.add_command(label='Open form A1', command=b.draw_graph) # PEP8: `=` without spaces when assigning arguments
# to use `b.draw_graph` you have to use `import b`, not `from b import *`
button = tk.Button(root, text="Open form A1", command=b.draw_graph)
button.pack()
root.mainloop()
if __name__ == '__main__':
main()
If you would use
from b import *
then you would have to use command=draw_graph instead of command=b.draw_graph
If you have b.py in subfolder with name other then you can do
from other import b
and still use command=b.draw_graph
or
import other.b
and then you has to use command=other.b.draw_graph
PEP 8 -- Style Guide for Python Code
EDIT:
I already wrote how to use code from subfolder but I repeat
if you have Folder1/main.py and Folder1/Folder2/B.py then in main.py you need only
from Folder2 import B
command=B.draw_graph
or
import Folder2.B
command=Folder2.B.draw_graph
(if file has upper case name B then module has also upper case name B)
It should work without adding folder to sys.path and without adding file Folder2/__init__.py
If you will have Folde1/main.py and Folder1/Folder2/Folder3/B.py then you need
from Folder2.Folder3 import B
command=B.draw_graph
or
import Folder2.Folder3.B
command=Folder2.Folder3.B.draw_graph
Eventually you can add current folder to sys.path before import
import os
import sys
BASE_DIR = os.path.abspath(os.path.dirname(__file__))
sys.path.append(BASE_DIR)
from Folder2 import B
#import Folder2.B
and it will work also when you run code from different folder
(different Current Working Directory - check print(os.getcwd()))
For example
cd ..
python Folder1/main.py
or
cd /
python /home/mypc/Destkop/Folder1/main.py
Use Toplevel() function
make the first file as you want like name and write this code (a.py for exemple)
from tkinter import *
from tkinter.ttk import *
from b import *
class app:
def __init__(self, root):
self.root = root
self.menu_bar()
self.root.mainloop()
def menu_bar(self):
self.app = app1()
self.menubar = Menu(self.root)
self.filemenu = Menu(self.menubar, tearoff=0)
self.filemenu.add_command(
label="Open A1", command=lambda: self.app.second(self.root))
self.filemenu.add_separator()
self.filemenu.add_command(label="Exit", command=self.root.quit())
self.menubar.add_cascade(label="File", menu=self.filemenu)
self.root.config(menu=self.menubar)
if __name__ == "__main__":
app(Tk())
and in the second file make sure that he name as you write in a.py(from filename import *) (b.py for the exemple) and write like this
class app1:
def second(self, root):
self.root = Toplevel(root)
Label(self.root, text="A2").pack(padx=20, pady=20)
this should solve you problem
Introduction
I am a student at university learning programming. My courses focus on Java, C# and C++ so I have some experience with OOP. Currently I'm busy with my co-op and the requirement is to create a GUI using Python and tkinter (both of which I'm learning as I go).
My problem is related specifically to Python OOP and inheritance across multiple files in multiple directories and I simply can't figure it out (its been 3 days)
If you don't want to go through multiple lines of shortened files and code examples, you can find the actual code here:
https://github.com/bkleynhans/Landsat-Buoy-Calibration.git
Then go to the bottom of the page to get to the jist of the question.
You will not be able to run the calibration system unless you have ModTran installed, which is an expensive licensed software. The GUI however should be fully operational with the only non-standard requirement being tkcalendar.
What I've Done
I've worked through the threads linked below as well as the links included in both by other members.
ImportError: cannot import name
ImportError: Cannot import name X
as well as
https://www.digitalocean.com/community/tutorials/understanding-class-inheritance-in-python-3
https://www.python-course.eu/python3_inheritance.php
https://chrisyeh96.github.io/2017/08/08/definitive-guide-python-imports.html
Unfortunately I can't seem to relate them to my problem whether it be because I'm not knowledgeable enough or because I'm just slow.
Folder Structure
My folder structure is as follows:
Z:.
│
│ tarca_gui
│
└───gui
│
│ __init__.py
│ tarca_gui.py
│
│
└───forms
│
│ input_notebook.py
│ status_frame.py
│ settings_frame.py
│ example_date_picker_supplied.py
│ settings_notebook.py
│ input_frame.py
│ help_menu.py
│ header_frame.py
│ progress_bar.py
│ __init__.py
│ menu_bar.py
│ example_date_picker.py
│ output_frame.py
│
└─
File Summaries
tarca_gui in the root is simply a bash script that changes into the working directory and executes the gui
cd ~/Landsat-Buoy-Calibration/gui
python3 tarca_gui.py
Placing the files and their code in here would be extensive clutter, however I'll paste the headers and structures. A GitHub link to the project is in the introduction section above.
Required Non-standard Libraries:
tkcalendar - https://pypi.org/project/tkcalendar/
tarca_gui.py - Launches the program from a linux terminal and builds the interface using tkinter. All the other files are derived based on the following structure
The Base Class
tarca_gui.py
from tkinter import *
from tkinter import messagebox
import inspect
import sys
import os
import pdb
class Tarca_Gui:
def __init__(self, master):
# Import gui paths
from forms import progress_bar
from forms import menu_bar
from forms import header_frame
from forms import input_frame
from forms import output_frame
from forms import status_frame
# Create the root Tkinter object
master.title('CIS Top Of Atmosphere Radiance Calibration System')
master.geometry('800x600')
master.resizable(False, False)
#master.configure(background = '#FFFFFF')
master.option_add('*tearOff', False)
# Create the Progressbar window - accessed via master.progressbar_window.progress_bar
progress_bar.Progress_Bar(master)
# Create the Menubar - accessed via master.menu_bar
menu_bar.Menu_Bar(master)
# Create the Header - accessed via master.header_frame
header_frame.Header_Frame(master)
# Create the Input Frame - accessed via master.
input_frame.Input_Frame(master)
# Create the Input Frame - accessed via master.
output_frame.Output_Frame(master)
# Create the Input Frame - accessed via master.
status_frame.Status_Frame(master)
# Calculate fully qualified path to location of program execution
def get_module_path():
filename = inspect.getfile(inspect.currentframe())
path = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
return path, filename
# Set environment variables to locate current execution path
def set_path_variables():
path, filename = get_module_path()
# find the Calibration program path
path_index = path.rfind('/')
# append gui paths
sys.path.append(path[:path_index])
sys.path.append(path)
sys.path.append(path + "/forms")
def on_closing(root):
if messagebox.askyesno("Quit", "Do you really wish to quit?"):
root.destroy()
def main():
set_path_variables()
root = Tk()
root.protocol("WM_DELETE_WINDOW", lambda: on_closing(root))
tarca_gui = Tarca_Gui(root)
root.mainloop()
if __name__ == "__main__": main()
progress_bar, menu_bar, header_frame, input_frame, output_frame and status frame are derived from (extend) targa_gui
Summaries of Derived Classes
progress_bar.py extends tarca_gui.py
from tkinter import *
from tkinter import ttk
import tarca_gui
class Progress_Bar(tarca_gui.Tarca_Gui):
def __init__(self, master):
menu_bar.py extends tarca_gui.py
from tkinter import *
from tkinter import ttk
import tarca_gui
import help_menu
from gui.forms import settings_frame
class Menu_Bar(tarca_gui.Tarca_Gui):
def __init__(self, master):
header_frame.py extends tarca_gui.py
from tkinter import *
from tkinter import ttk
from forms import input_frame
class Header_Frame(input_frame.Input_Frame):
def __init__(self, master):
input_frame.py extends tarca_gui.py
from tkinter import *
from tkinter import ttk
import tarca_gui
from gui.forms import input_notebook
class Input_Frame(tarca_gui.Tarca_Gui):
def __init__(self, master):
output_frame.py extends tarca_gui.py
from tkinter import *
from tkinter import ttk
import tarca_gui
class Output_Frame(tarca_gui.Tarca_Gui):
def __init__(self, master):
status_frame.py extends tarca_gui.py
from tkinter import *
from tkinter import ttk
import tarca_gui
class Status_Frame(tarca_gui.Tarca_Gui):
def __init__(self, master):
The remaining classes: help_menu, settings_frame, settings_notebook, header_frame and input_notebook are derived from (extend) other classes
header_frame.py extends input_frame.py
from tkinter import *
from tkinter import ttk
from forms import input_frame.py
import pdb
class Header_Frame(input_frame.Input_Frame):
def __init__(self, master):
input_notebook.py extends input_frame.py
from tkinter import *
from tkinter import ttk
from tkinter import filedialog
from gui.forms import input_frame
from tkcalendar import Calendar, DateEntry
from datetime import date
class Input_Notebook(input_frame.Input_Frame):
def __init__(self, master):
help_menu.py extends menu_bar.py
from tkinter import *
from tkinter import ttk
import time
import threading
import menu_bar
class Help_Menu(menu_bar.Menu_Bar):
def __init__(self, master):
settings_frame.py extends settings_notebook.py
from tkinter import *
from tkinter import ttk
from tkinter import messagebox
from gui.forms import menu_bar
from gui.forms import settings_notebook
class Settings_Frame(menu_bar.Menu_Bar):
def __init__(self, master):
settings_notebook.py extends settings_frame.py
from tkinter import *
from tkinter import ttk
from tkinter import filedialog
from gui.forms import settings_frame
class Settings_Notebook(settings_frame.Settings_Frame):
def __init__(self, master):
The Problem and Question
Firstly, PYTHONPATH is updated when the gui is launched through functions you can view in the base class.
Secondly, I understand that currently the classes are not all imported in the same way, they were and have been changed in my efforts to find the problem and will be standardized as soon as the problem has been resolved.
The Problem
The entire GUI works fine until I try to import Settings_Frame into settings_notebook.py
Error received
% ./tarca_gui
Traceback (most recent call last):
File "tarca_gui.py", line 104, in <module>
if __name__ == "__main__": main()
File "tarca_gui.py", line 100, in main
tarca_gui = Tarca_Gui(root)
File "tarca_gui.py", line 31, in __init__
from forms import menu_bar
File "/cis/otherstu/bxk8027/Landsat-Buoy-Calibration/gui/forms/menu_bar.py", line 20, in <module>
import help_menu
File "/cis/otherstu/bxk8027/Landsat-Buoy-Calibration/gui/forms/help_menu.py", line 21, in <module>
import menu_bar
File "/cis/otherstu/bxk8027/Landsat-Buoy-Calibration/gui/forms/menu_bar.py", line 21, in <module>
from gui.forms import settings_frame
File "/cis/otherstu/bxk8027/Landsat-Buoy-Calibration/gui/forms/settings_frame.py", line 21, in <module>
from gui.forms import settings_notebook
File "/cis/otherstu/bxk8027/Landsat-Buoy-Calibration/gui/forms/settings_notebook.py", line 25, in <module>
class Settings_Notebook(settings_frame.Settings_Frame):
AttributeError: module 'gui.forms.settings_frame' has no attribute 'Settings_Frame'
Findings
I believe this to be due to circular imports because settings_frame imports settings_notebook and vica versa.
Confusion
I understand that circular references should be avoided where possible, however the way I currently understand Python OOP, I need to import settings_notebook into settings_frame in order to construct it, but at the same time I need to import settings_frame into settings_notebook in order to extend it (settings_notebook should be a child of settings_frame)
The Question
I don't know what I'm doing wrong.
Is it import related, or is it the way that I structured my classes?
If I am understanding the class structure (with imports) incorrectly, please explain what I did wrong so I can learn and not make the same mistake again.
Any other suggestions pertaining to the could would be very much appreciated.
In Conclusion
If you made it this far, firstly, thank you very much.
As mentioned I'm at university and learning C++, C#, Java, Python, HTML, CSS, JavaScript, PHP, SQL, Unity and Unreal engine at the same time (sometimes I get confused with concepts between them), so any suggestions relating to any part of my code would be greatly appreciated.
This code is really hard to untangle, but I think the root of the problem is that you are trying to use inheritance to share data between classes. That is not what inheritance is for.
When B inherits from A, that doesn't mean that B shares A's data, it means that B is an exact copy of A with some enhancements. In effect, you have two A's - the original, and a new one that has some additional features.
For example, you have a class named Tarca_Gui. This appears to be the main class. It has a status bar, a menu bar, and so on. When you inherit from Tarca_Gui, that new class also has a status bar, a menu bar, and so on. The two classes don't share any data.
Instead of inheritance, you need to be using composition. The difference is that, with inheritance Menu_Bar is a Tarca_Gui, but what you really want is for Tarca_Gui to have a Menu_Bar.
It's impossible for me to fix your code since you didn't provide a minimal reproducible example, but the first thing you need to do is remove Tarca_Gui from the definition of each class. Then, pass the instance of Tarca_Gui to the various other objects.
In other words:
class Tarca_Gui():
def __init__(self, master):
...
self.menu_bar = Menu_Bar(self)
self.header_frame.Header_Frame(self)
self.input_frame = Input_Frame(self)
self.output_frame = Output_Frame(self)
self.status_frame = Status_Frame(self)
...
class Menu_Bar():
def __init__(self, tarca_gui):
self.tarca_gui = tarca_gui
...
class Progress_Bar():
def __init__(self, tarca_gui):
self.tarca_gui = tarca_gui
...
class Header_Frame():
def __init__(self, tarca_gui):
self.tarca_gui = tarca_gui
...
... and so on ...
Then, inside each of those objects, if they need something that is managed by Tarca_Gui, they can use self.tarca_gui to reference it. For example, if you need access to the master widget you could use self.tarca_gui.master.
Similarly, nothing should be inheriting from Menu_Bar or Input_Frame or Settings_Frame.
For more information about inheritance vs composition, see Difference between Inheritance and Composition
I have located this useful code for Tkinter animations from https://www.daniweb.com/programming/software-development/threads/396918/how-to-use-animated-gifs-with-tkinter ,supplied by "vegaseat".
I have adapted a similar design for displaying gifs animations to a project. I am wishing to implement this as a function to certain areas of a script, e.g. importing modules etc. I have tried a few approaches but when I called this as a function, it first runs the animation and then imports the module (as we would expect).
I guess I am exploring ways to get this to work concurrently...while the script is importing modules( or running another process where I wish to display the animation), the animation would be displayed, and then disappear, until the next call. Suggestions would be appreciated.
Thanks a lot.
# mimic an animated GIF displaying a series of GIFs
# an animated GIF was used to create the series of GIFs
# with a common GIF animator utility
import time
from Tkinter import *
root = Tk()
imagelist = ["dog001.gif","dog002.gif","dog003.gif",
"dog004.gif","dog005.gif","dog006.gif","dog007.gif"]
# extract width and height info
photo = PhotoImage(file=imagelist[0])
width = photo.width()
height = photo.height()
canvas = Canvas(width=width, height=height)
canvas.pack()
# create a list of image objects
giflist = []
for imagefile in imagelist:
photo = PhotoImage(file=imagefile)
giflist.append(photo)
# loop through the gif image objects for a while
for k in range(0, 1000):
for gif in giflist:
canvas.delete(ALL)
canvas.create_image(width/2.0, height/2.0, image=gif)
canvas.update()
time.sleep(0.1)
root.mainloop()
EDIT: I am attempting to implement the code,below, per some helpful suggestions. The goal is to begin the animation, while the application is importing the modules in the "IMPORTS" function, and then have it destroyed after the imports are completed.
# Import modules
from Tkinter import *
from PIL import ImageTk
from PIL import Image
import os,time
from os.path import dirname
from os.path import join
def IMPORTS():
import tkMessageBox
from ttk import Combobox
import csv,datetime
import xlrd,xlwt
import getpass
import traceback
import arcpy
from arcpy import AddMessage
import win32com.client
inGif = #root image (.gif)
FramesFolder = #Folder containing frames of the root image
W=Toplevel()
W.wm_overrideredirect(True) # I wish to only display the widget spinning without the window frame
imagelist = [os.path.join(FramesFolder,s) for s in os.listdir(FramesFolder) if not s.endswith('db')]
# extract width and height info
photo = PhotoImage(file=imagelist[0])
width = photo.width()
height = photo.height()
canvas = Canvas(W,width=width, height=height)
canvas.pack()
# create a list of image objects
giflist = []
for imagefile in imagelist:
photo = PhotoImage(file=imagefile)
giflist.append(photo)
timer_id = None
def start_loading(n=0):
global timer_id
gif = giflist[n%len(giflist)]
canvas.create_image(gif.width()//2, gif.height()//2, image=gif)
timer_id = W.after(100, start_loading, n+1) # call this function every 100ms
def stop_loading():
if timer_id:
W.after_cancel(timer_id)
canvas.delete(ALL)
start_loading()
IMPORTS()
stop_loading()
# The spinning widget should be completely destroyed before moving on...
It is returning
"NameError: name 'tkMessageBox' is not defined"
You can use Tk.after() and Tk.after_cancel() to start and stop the animation:
timer_id = None
def start_loading(n=0):
global timer_id
gif = giflist[n%len(giflist)]
canvas.create_image(gif.width()//2, gif.height()//2, image=gif)
timer_id = root.after(100, start_loading, n+1) # call this function every 100ms
def stop_loading():
if timer_id:
root.after_cancel(timer_id)
canvas.delete(ALL)
Then, you can call start_loading() before the long process and call stop_loading() after the long process:
start_loading()
long_process() # your long process
stop_loading()
Here is a minimum working example of my code.
I am trying to plot a live graph using matplotlib by taking some inputs from the user via gui. For building the gui, I used the library easygui
However, there is one problem:
the graph stops building while taking an update from the user and I wish it to continue. Is there something that I'm missing here.
#!/usr/bin/env python
from easygui import *
from matplotlib.pylab import *
import numpy
import random
n = 0
fig=plt.figure()
x=list()
y=list()
plt.title("live-plot generation")
plt.xlabel('Time(s)')
plt.ylabel('Power(mw)')
plt.ion()
plt.show()
calculated=[random.random() for a in range(40)]
recorded=[random.random() for a in range(40)]
possible=[random.random() for a in range(5)]
plt.axis([0,40,0,10000])
for a in range(0, len(recorded)):
temp_y= recorded[a]
x.append(a)
y.append(temp_y)
plt.scatter(a,temp_y)
plt.draw()
msg = "Change"
title = "knob"
choices = possible
if a>9:
b = (a/10) - numpy.fix(a/10)
if b==0:
choice = choicebox(msg, title, choices)
print "change:", choice
here is the download link for easygui
sudo python setup.py install
based on your version of linux or OS. use the following link
Thanks to J.F. Sebastian
import easygui
from Tkinter import Tk
from contextlib import contextmanager
#contextmanager
def tk(timeout=5):
root = Tk() # default root
root.withdraw() # remove from the screen
# destroy all widgets in `timeout` seconds
func_id = root.after(int(1000*timeout), root.quit)
try:
yield root
finally: # cleanup
root.after_cancel(func_id) # cancel callback
root.destroy()
with tk(timeout=1.5):
easygui.msgbox('message') # it blocks for at most `timeout` seconds