I am working on a program that allows me to directly edit a word document through a tkinter application. I am trying to link the tkinter input from my gui file to my main file so that I can execute my docx functions. When I try to execute my code this way, it tells me that entry in entry.get() is not defined. When I try to import this from main, I receive a circular import error.
main.py
from docx import Document
from docx.shared import Inches
import os
os.chdir("\\Users\\insanepainz\Desktop")
doc = Document('TemplateTest.docx')
paragraphs = doc.paragraphs
def WebsiteChange():
website = entry.get()
print(website)
master.quit()
for paragraph in doc.paragraphs:
if '^website' in paragraph.text:
paragraph.text = gui.entry
print(paragraph.text)
doc.save(doc)
pass
gui.py
import main
from tkinter import *
master = Tk()
#------------Web Entry Window
Label(master, text="Website Name: ").grid(row=0, sticky=W)
entry = Entry(master)
entry.grid(row=0, column=1)
# Connect the entry with the return button
submit = Button(master, text="Submit", command=main.WebsiteChange)
submit.grid(row=1)
# Centers the program window
master.eval('tk::PlaceWindow %s center' % master.winfo_pathname(master.winfo_id()))
mainloop()
I have been struggling to understand this concept for awhile. Circular errors are giving me a headache. Any help would be greatly appreciated.
The import mechanism is designed to allow circular imports. But one must remember the following:
The name of the main module created from the startup script is __main__, rather than as its filename minus .py. Any other file importing the startup script must import __main__, not import filename. (Otherwise, a second module based on the startup script will be created with its normal name.)
Execution of the code in a module is paused at each import. The order of initial imports is important as the last module in the chain is the first to be run to completion. Each object within modules must be available when the reference is executed. References within function definitions are not executed during the import process.
Applying the above to your pair, I assume that gui.py is the startup script. Python will immediate create an empty module object as the value of sys.modules['__main__']. Somain.pyshould importgui.pywithimport main as gui(the name change is just for convenience). Within the function definition, you should be able to usegui.entrywithout problem since there will be no attempt to lookupgui.entryuntil the function is called. I suggest addingentry = gui.entryas the first line of the function and usingentry` in the two places needed.
The following pair of files run as desired when tem2.py is run.
# tem2.py
import tem3
a = 3
print(tem3.f())
# tem3.py
import __main__ as tem2
def f():
return tem2.a
Move the definition of entry into a third file and import it in both files.
You can pass the entry to WebsiteChange:
def WebsiteChange(entry):
website = entry.get()
submit = Button(master, text="Submit",
command=lambda e=entry: main.WebsiteChange(e))
Related
Can some one help me.।
I want to open a python script using a button which is present in another python Script.।
So I want that when I click on that button my main. Py file open directly
Screensht of project 2 is given below.
I tried creating a function but not working.
Please any one help this is my college project
enter image description here
Is this what you're trying to achieve ?
main.py
import second_file
import Tkinter
import tkMessageBox
top = Tkinter.Tk()
B = Tkinter.Button(top, text ="Execute function from second file", command = second_file.my_function)
B.pack()
top.mainloop()
second_file.py
def my_function():
#do_stuff
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
I am a newbie in Python and am creating a Tkinter GUI that basically allows users to find desired keywords in .docx files. I have two buttons that both load a pickle file and only one may also add content to the file and save. After using the file under one function(button) and trying to load it up again under the other function(button) the file does not load. It will only load up again after I fully exit the program and run it again. I am not using classes for this program, but I feel that I may have to. I am just not able to bounce between these functions and successfully pass the file. Any advice would be greatly appreciated. Here is the code that may be most useful for this question:
from Tkinter import *
import tkMessageBox
import sys,os,glob,pickle
root = Tk()
root.geometry('400x300')
root.title('Potential Candidate Engine')
Pickle_File = ('Diction.pickle')
if os.path.exists(Pickle_File):
with open(Pickle_File,'r') as rPF:
Dictionary = pickle.load(rPF)
def Clear_Window():
RETURN = sys.executable
os.execl(RETURN, RETURN, * sys.argv)
def SR():
global Dictionary
### Scan the document here ###
def CNP():
global Dictionary
### User adds content here, file saves ###
That 'Clear_Window()' function is just a workaround to return to the main window after the user is done with one function and would like to use the other. It is executed when the RETURN button is pushed
I'd like to make auto test tool with Python. One thing I'd like to achieve is updating Test log in log window. However, all logs are displayed after finishing Test process. How can I show log during process?
In addtion, during processing, GUI stops working with error message"Not Responding". How to resolve it? thanks for your help in advance.
(Window 7, 64bit, Python 3.4, tkinter, matplotlib)
==========================================================================
from tkinter import *
from matplotlib import pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
from time import sleep
root= Tk()
root.title("Auto Test")
root.geometry('300x700')
root.configure(background='white')
datac1_frame = Frame(root,bg="white",width=400, height=30)
datac1_frame.pack(side=TOP, anchor = W,padx= 5,fill=BOTH)
data1_frame = Frame(root,bg="white",width=400, height=280)
data1_frame.pack(side=TOP, anchor = W,padx= 5,fill=BOTH)
log_frame = Frame(root,bg="blue",width=400, height=80)
log_frame.pack(side=TOP, anchor = N,padx= 5,fill = Y)
#Output Box
logmes = Text(log_frame,width=800)
logmes.pack()
class autotest:
def DUT_config(self):
sleep(1)
logmessage('DUT configuration')
def measurement(self):
sleep (2)
logmessage('DUT is under measurement')
def freqentry(frame,text, command = None):
label = Label(frame,text='Channel', bg = 'chartreuse',
width= 10).pack(side = LEFT, padx=10, pady = 2)
entry = Entry(frame, width = 18, text = text,
justify = CENTER).pack(side = LEFT)
button = Button(frame, text = "Run", bg = "lightsteelblue",
width = 5,padx=4, command = command).pack(side = LEFT)
def clickrun():
logmessage ('button is clicked')
for i in range(5):
logmessage('# of try', i)
at.DUT_config()
sleep(1)
at.measurement()
def logmessage(*args):
logmes.insert(END, args)
logmes.insert(END, '\n')
logmes.see(END)
#Channel, freq, Run button alignment
freqentry(datac1_frame, '2000MHz', clickrun)
## Data Gathering
f_0 = Figure(figsize=(2.5,2.5), dpi =100)
a_0 = f_0.add_subplot(111)
a_0.xaxis.grid(True)
a_0.yaxis.grid(True)
a_0.plot ()
## Display on the plot
canvas = FigureCanvasTkAgg(f_0, data1_frame)
canvas.show()
canvas.get_tk_widget().pack(side=LEFT)
at = autotest()
plt.show()
root.mainloop()
Hi there and welcome to StackOverflow.
First issue I see is your handling of scope. I suppose you posted this as a Minimal, Complete, and Verifiable example.
If this is your complete code, please be advised that there are some issues you should resolve. Your function def logmessage(*args) uses the variable logmes which is defined outside your function and additionaly used in other functions as well.
Like in most programming languages, the scope of a function limits access of variables in python. If you want to use the logmes listbox "globally" declared, you need to tell that to the functions as well by declaring the variable global inside the function (sample below)
# We are inside the main routine here - global scope
root= Tk()
log_frame = Frame(root,bg="blue",width=400, height=80)
log_frame.pack(side=TOP, anchor = N,padx= 5,fill = Y)
#Output Box
logmes = Text(log_frame,width=800)
logmes.pack()
# Here come functions having their own scope
def logmessage(*args):
# Use variables from global scope - global declaration
#################################
global logmes
#################################
logmes.insert(END, args)
logmes.insert(END, '\n')
logmes.see(END)
Using global variables is often seen as some kind of a bad habit, as it reduces the ways of reusing your code in other purposes. I personally prefer using classes in modules and putting everything that belongs together inside a class. This results in a module structure like
Module Header: e.g. commentary lines, version, author, shebang, etc.
Import Section: here i import whatever i need
Class and Function Section: here i define my classes and functions
Main Routine: starting with if __name__=="__main__": I start processing if the script is called and not imported, function calls happen only here
Unfortunately I see a second issue as well - inside your "Import Section" you are importing from matplotlib import pyplot as plt. Later on in your main routine you are calling plt.show. I am not using matplotlib often, but if I remember it correctly, you first define a pyplot Object and then call the show routine on the object, not the Module itself.
Do you receive any error messages inside your python console output? (Supposing you are calling the script from the commandline) or do you call it by double-clicking it? How do you store the file? I am focusing on the file-extension here, as it does make a difference if you store it as *.pyw or *.py in having or not having a console output window.
Another issue I just recognized is your class definition. As the documentation of the class module in python states out, a class is sth. that supports
two kinds of operations: attribute references and instantiation.
You are using your class as sth. like a function wrapper. You are not using inheritance nor are you declaring an __init__ funcionality to instantiate class variables.
It is no question that python gives you the ability to do so, but please keep in mind that your use of a class does more do sth. a module would do. Declare a namespace for certain functions that do not need more than the parameters passed (if any).
I do really recommend you have a very close look at the class documentation. This really helps improving your code and reduces the necessity to be slowed down by asking questions and waiting for replys on stuff the documentation can tell you directly and using simple examples.
Please do not see my last comment as any offense as this is definitely not intended here, just as a recommendation to help you improve in your work.
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)