I am trying to change a program's behaviour on the fly by editing its source file (under Python 3.4.2, Windows 8.1). My program is a tkinter GUI with a button that sums two values, but I want to be able to change the button's behaviour. I am currently trying to do this by editing the source file (changing, say, the addition to subtraction), saving it, and then clicking a button whose callback function imports the source file. I want my code changes to be reflected in the running GUI without having to exit and restart the program. I also want this import to only recompile the lines that I changed, rather than the entire file.
The program, reload0.py:
import time
import serial
import sys
import os
import tkinter as tk
from tkinter import ttk
from tkinter import *
from tkinter import messagebox
from tkinter import filedialog
try:
import Tkinter # Python 2
import ttk
except ImportError:
import tkinter as Tkinter # Python 3
import tkinter.ttk as ttk
mGui = Tk()
mGui.title("GUI")
mGui.geometry('400x200+100+100')
def mOp():
num1 = value1.get()
num2 = value2.get()
Op=num1+num2
name1.set('Sum')
name2.set(Op)
def mReLoad():
import reload0.py
mGui.update()
def mCheck():
if len(name1.get()) == 0:
name1.set('name1')
mGui.update()
if (len(name2.get()) == 0):
name2.set('name2')
mGui.update()
try:
print(value1.get())
except ValueError:
value1.set(0)
mGui.update()
try:
print(value2.get())
except ValueError as ValE:
value2.set(0)
mGui.update()
print(ValE)
value1 = DoubleVar()
value2 = DoubleVar()
name1 = StringVar()
name2 = StringVar()
mButtonSave = Button(mGui, text = "Operation", command = mOp, fg = 'Red').place(x=150,y=80)
mButtonLoad = Button(mGui, text = "ReLoad Operation", command = mReLoad, fg = 'Red').place(x=150,y=110)
mButtonLoad = Button(mGui, text = "Check", command = mCheck, fg = 'Red').place(x=150,y=140)
tText1 = Entry(mGui, textvariable = name1).place(x=10,y=80)
tText2 = Entry(mGui, textvariable = name2).place(x=10,y=100)
vText1 = Entry(mGui, textvariable = value1).place(x=10,y=120)
vText2 = Entry(mGui, textvariable = value2).place(x=10,y=140)
For your purpose of changing button functionality there are easy ways than changing source code, and as commented it's not possible.
judging from another question i saw of yours you are quite new to python programming. I would recommend spending some time on some basic tutorials getting to know python and some programming concepts first.
for instance
import reload.py
should simply be
import reload
https://wiki.python.org/moin/BeginnersGuide/NonProgrammers
read a book, do some examples, and so enough you will be the one answering the questions here, good luck!
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.
import os
import tkinter as tk
from tkinter import *
from tkinter.ttk import *
root = Tk()
variable = StringVar(root)
variable = StringVar(root)
variable.set('GB')
w = Combobox(root, values = choices)
w.pack(); root.mainloop()
choices = ['']
msedgelocation= 'my msedge location'
chromelocation= 'my chrome location'
if os.path.exists(msedgelocation):
# add msedge to choices
else:
if os.path.exists(chromelocation):
# add chrome to choices
This will only add 1 option, How do I change the script so it adds multiple options?
Preferably just code and an explanation, but anything helps. Thanks!
EDIT: Also a submit box would be nice
I improved Your code a bit:
from tkinter import Tk, StringVar
from tkinter.ttk import Combobox
import os
def get_choice(event):
os.startfile(choices[event.widget.get()])
root = Tk()
variable = StringVar()
variable.set('GB')
choices = {'GB': 'gb.exe', 'AUS': 'aus.exe', 'USA': 'usa.exe', 'Chrome': 'chrome.exe'}
c_box = Combobox(root, values=list(choices.keys()), textvariable=variable, state='readonly')
c_box.pack()
c_box.bind('<<ComboboxSelected>>', get_choice)
root.mainloop()
First of I got all the info about the combobox here where it was put in simple words.
The other thing is that You should name variables with meaningful variable names not just one letter names, especially if You plan on using the variable.
Also as I mentioned in the comments, it is suggested that You import only what You need, as You can see in my provided code.
Lastly, as #acw1668 already mentioned in comments the code after .mainloop() will only get executed when the window closes.
I am new to tkinter
import datetime as dt
from tkinter import *
from tkinter import messagebox
dt1 = dt.datetime.now().strftime("%Y""%m""%d")
time1 = dt.datetime.now().strftime('%H:%M:%S')
msg1= dt1+" "+time1+ " Test Message XXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
master = Tk()
top = Tk()
top.geometry("100x100")
messagebox.showinfo("information", msg1)
top.mainloop()
I have basically 3 issues in this basic code
It is creating additional blank windows along with my message which is not required. How to avoid this ?
I want to display my message into single line how can i do this ?
How to change font and color of this message ?
I am building my first larger Python application using tkinter, python 3.6.3 and window OS. The GUI for the application consists of a Notebook with several tabs. Each of the tabs in turn contains a Labelframe which in turn contains a number of other widgets.
When searching Stackflow, I found the idea to lets each labelFrame be a class. Thereafter import the class in the main.py and finally creating an instance of the class.
Now when pressing the button 'Start' in tab1 I would like to execute the 'printThis' function. Ideally I would like to use the function defined in the script main.py. It would also be interested in knowing how to call the 'printThis' method withing the Run_Test_Window class. Unfortunately I have not solved either problem.
Interestingly the program actually prints "Now successful" without that I do anything but when I press the 'Start'-button nothing happens.
Grateful for help! Thanks!
main.py
import tkinter as tk
import tkinter.ttk as ttk
import RunTestClass as RT
def printThis():
print('Successful')
root = tk.Tk()
note = ttk.Notebook(root)
note.grid()
tab1 = ttk.Label(note, width = -20)
note.add(tab1, text = " Run Test ")
window1 = RT.Run_Test_Window(tab1)
root.mainloop()
RunTestClass.py
import tkinter as tk
import tkinter.ttk as ttk
# from main import printThis
class Run_Test_Window:
def printThis(self):
print('Now successful!')
def __init__(self,tab1):
runTestLabelFrame = ttk.LabelFrame(text ="Run Test", padding =10)
runTestLabelFrame.grid(in_ = tab1, padx = 20, pady = 20)
self.startButton = ttk.Button(runTestLabelFrame, text="START",command=self.printThis())
self.startButton.grid(row=5, column=1, padx = 10)
If I'm correct you want the button to use the printThis() from main. This can be done by adding the following in your main:
rt = RT.Run_Test_Window(tab1)
rt.startButton.configure(command=printThis)
To call the printThis() defined in RunTestClass, use (also in main)
rt.printThis()
Note: leave the brackets when creating the button in the command argument. So change it to this:
self.startButton = ttk.Button(runTestLabelFrame, text="START",command=self.printThis)
I want to launch an "Open File" dialog in Tkinter in Python 2.7.
My code starts with:
from Tkinter import Frame, Tk, BOTH, Text, Menu, END
import tkFileDialog as tkfd
import fileinput
root = Tk()
global strTab
strTab = ""
def openTab(event):
r = tkfd.askopenfilename()
strTab = unicodedata.normalize('NFKD', r).encode('ascii','ignore')
Later in the code I have:
btnLoadTab = Button(root,
text="Load Tab",
width=30,height=5,
bg="white",fg="black")
btnLoadTab.bind("<Button-1>", openTab)
btnLoadTab.pack()
root.mainloop()
When I press the button an "Open File" dialog is shown, but when I select a file it closes and the button remains "clicked".
If I later call to strTab outside of openTab, it remains equal to "".
You can find workable example here: http://www.python-course.eu/tkinter_dialogs.php