how do you open two tkinter Windows one after the other.? - python-3.x

I am fairly new to python programming with its concept of class which is very different of languages like java, c++, c# ... and also the Tkinter library. I am trying to do something basic. First creating a frame that will allow the user to enter a string value; store that string value in memory then exit that frame. Creating a new file browser that will allow you to select a specific file then rename the chosen file with the string stored in memory earlier. I do not have any specific snippet of code to do that but I have two pieces of codes that could be combined to give me the result I want.
enter code here
# This is the snippet for the input user
def printtext():
global e
string = e.get()
return string
from Tkinter import *
root = Tk()
root.title('Name')
e = Entry(root)
e.pack()
e.focus_set()
b = Button(root,text='okay',command=printtext)
b.pack(side='bottom')
root.mainloop()
# This is for the file browser
import Tkinter,tkFileDialog
root = Tkinter.Tk()
file = tkFileDialog.askopenfile(parent=root,mode='rb',title='Choose a file')

Why don't you try with asksaveasfilename like in this example.But if you want to use file_path=askopenfilename with entry, than you would have to use OS library, with function os.rename (i think) .This code is written in python 3 so if you are using python2 than just change names of libraries.
from tkinter import *
import tkinter.filedialog as fd
def main():
root = Tk()
root.title('Name')
#e = Entry(root)
#e.pack()
#e.focus_set()
b = Button(root,text='okay',command= lambda:printtext(e))
b.pack(side='bottom')
root.mainloop()
def printtext(e):
#string = e.get()
#print(string)
file = fd.asksaveasfile(title='Choose a file')
#print(file)
main()

Related

Returning variable from a function

I have a main function page and i linked the next page with a button
when i click the button it executes a function in the main page but.
i want to use the result from the function in another file as a variable
########main.py
class Main(object):
def __init__(self,master):
self.master = master
mainFrame = Frame(self.master)
mainFrame.pack()
topFrame= Frame(mainFrame,width=1050,height =50, bg="#f8f8f8",padx =20, relief =SUNKEN,
borderwidth=2)
topFrame.pack(side=TOP,fill = X)
self.btnselfolder= Button(topFrame, text="Select Folder", compound=LEFT,
font="arial 12 bold", command=self.selectFolder)
self.btnselfolder.pack(side=LEFT)
def selectFolder(self):
print("folder")
return folder
################# selectfolder page
class Page2(Toplevel):
def __init__(self):
Toplevel.__init__(self)
self.geometry("450x300")
self.title("page2")
self.resizable(False,False)
self.topFrame = Frame(self, width=350,height=150, bg="white")
self.topFrame.pack(fill=X)
# call the function from main.py and it will give me the same output folder
y = selectFolder()
Since the selectFolder method is not static, you'll have to access it using instance. Like this:
main = Main()
folder = main.selectFolder()
folder should hold the value you returned.
I'm afraid when i just copied and pasted your code into my IDLE directly, it immediately presented me with naming errors. Not even a Tkinter window popped up. So to clear things up I would go about making a Tkinter window like the following. Also bare in mind I don't really use or know how to integrate classes with Tkinter itself, but I quickly learned how to by your mistakes :)
# import tkinter from the libraries
from tkinter import *
import os
# the Zen of Python
#import this
# declare the tkinter window variable
# scroll to bottom to see mainloop
root = Tk()
########main.py
# folder is not defined as a variable
# but i recommend looking into
# using system of which i imported
# for you. You can research how to
# use it yourself for good practice
# i am sorry if i am wrong about this
# but my impression is you're trying to
# use the OS to select a folder from a
# directory. So the 'selectFolder' function
# should not be declared as a method within the class
# therefore rendering the Page2 class useless.
def selectFolder():
print("folder")
# return will result in an error
# because it has not been declared as a variable
# return folder
class Main():
# all instances instantiated (created)
# within the __init__ method
# must be declared in the parentheses
def __init__(self, topFrame, btnselfolder):
# instantiate the topFrame object
self.topFrame = topFrame
# instantiate the btnselfolder
self.btnselfolder = btnselfolder
# pro tip - when having multiple
# arguments within an object, then
# to keep it clean and easy to read
# space out the code like i have for
# you. You should also read the "Zen of Python"
# which is at the top as 'import this'
# however i have commented it out for you
topFrame = Frame(root,
width=1050,
height = 50,
bg = "#f8f8f8",
padx = 20,
relief = SUNKEN,
borderwidth=2)
topFrame.pack(side=TOP, fill = X)
btnselfolder = Button(topFrame,
text = "Select Folder",
compound=LEFT,
font = "arial 12 bold",
command = selectFolder).pack()
# mainloop() method will keep the window open
# so that it doesn't appear for a millisecond
# and dissapear :)
root.mainloop()
# I hope this has been a big help
# Thanks for posting this question! :-)
# Enjoy your day, good luck and be safe in Lockdown!
Thanks again for the question, I thoroughly enjoyed solving it or at least giving you some guidence! :)

Is there a way of accessing the methods variables without calling the method?

I want to make a simple GUI that will allow user to pick an excel file to load the data from that will later be used for math calculations. Both modules work correctly when separate. But when I try to use my GUI as an import into my main file I am unable to access the needed var without calling the class method which in turn iterates it. It is troublesome because it is supposed to use this function only after the button press.
Is there something fundamentally wrong that I am doing?
GUI script
import tkinter as tk
import tkinter.filedialog as tkf
class TestClass():
def __init__(self, master):
frame = tk.Frame(master)
frame.pack()
self.dialogButton = tk.Button(frame, text="choose", command=self.chooseFile)
self.dialogButton.pack(side=tk.BOTTOM)
def chooseFile(self):
global filename
filename = tkf.askopenfilename()
print(filename)
Import script
import tkinterTest as tt
import tkinter as tk
root = tk.Tk()
classObject = tt.TestClass(root)
var = classObject.chooseFile()
print(var)
root.mainloop()
I want to access the path string only with the GUI so that it gives me the string only after I press the button to select the file not right after the program starts.

Defining a list of files using Tkinter to use for analysis. Having a hard time accessing the variables globally. (Python 3)

I hope all is well. Fairly new to programming, so please bear with me.
I am working on a GUI using tkinter that would prompt me to select a set of files that would be used to perform some analysis. I wish to store these files in a list that I can reference later. There are two required files, a DBC file and an ASC file. What I am having issues with is being able to reference the file(s) outside of the functions I have defined. I have tried defining it as a global variable (which I have read is not advisable as it can lead to problems down the road). I get an error saying dbfiles or ascfiles is not defined when just trying to print. Below is what I have written so far:
import tkinter as tk
from tkinter import messagebox
from tkinter import filedialog
root = tk.Tk()
root.geometry("500x700")
def dbbutton():
dbfiles = filedialog.askopenfilenames(parent=root, title='Select .DBC File(s)')
dbfiles = root.tk.splitlist(dbfiles)
for file1 in dbfiles:
L1.insert(tk.END, file1)
return dbfiles
def ascbutton():
ascfiles = filedialog.askopenfilenames(parent=root, title='Select .ASC File(s)')
ascfiles = root.tk.splitlist(ascfiles)
for file2 in ascfiles:
L2.insert(tk.END, file2)
return ascfiles
b1 = tk.Button (root, text= "Select Database File(s)", command = dbbutton)
b1.pack()
L1 = tk.Listbox(root, selectmode = "multiple", height = 10, width = 80)
L1.pack()
b2 = tk.Button (root, text = "Select ASC File(s)", command = ascbutton)
b2.pack()
L2 = tk.Listbox(root, selectmode = "multiple", height = 10, width = 80 )
L2.pack()
root.mainloop()
What is the most effective way for me to reference these files outside of the functions?
Create the file list outside the function and then append to it inside the function:
ascfile_list = [] # Create list to hold filenames
def ascbutton():
filename_list = filedialog.askopenfilenames(parent=root, title='Select .ASC File(s)')
for filename in filename_list:
L2.insert(tk.END, filename)
ascfile_list.append(filename) # Append filename to list

Tkinter python 3.5 choose files from file system and assign their path [duplicate]

what I want to do is to select multiple files
using the tkinter filedialog
and then add those items to a list.
After that I want to use the list to process
each file one by one.
#replace.py
import string
def main():
#import tkFileDialog
#import re
#ff = tkFileDialog.askopenfilenames()
#filez = re.findall('{(.*?)}', ff)
import Tkinter,tkFileDialog
root = Tkinter.Tk()
filez = tkFileDialog.askopenfilenames(parent=root,title='Choose a file')
Now, I am able to select multiple files,
but I dont know how to add those filenames to the list.
any ideas?
askopenfilenames returns a string instead of a list, that problem is still open in the issue tracker, and the best solution so far is to use splitlist:
import Tkinter,tkFileDialog
root = Tkinter.Tk()
filez = tkFileDialog.askopenfilenames(parent=root, title='Choose a file')
print root.tk.splitlist(filez)
Python 3 update:
tkFileDialog has been renamed, and now askopenfilenames directly returns a tuple:
import tkinter as tk
import tkinter.filedialog as fd
root = tk.Tk()
filez = fd.askopenfilenames(parent=root, title='Choose a file')
askopenfilenames
returns a tuple of strings, not a string.
Simply store the the output of askopenfilenames into filez (as you've done) and pass it to the python's list method to get a list.
filez = tkFileDialog.askopenfilenames(parent=root,title='Choose a file')
lst = list(filez)
>>> type(lst)
<type 'list'>
Putting together parts from above solution along with few lines to error proof the code for tkinter file selection dialog box (as I also described here).
import tkinter as tk
from tkinter import filedialog
root = tk.Tk()
root.withdraw()
root.call('wm', 'attributes', '.', '-topmost', True)
files = filedialog.askopenfilename(multiple=True)
%gui tk
var = root.tk.splitlist(files)
filePaths = []
for f in var:
filePaths.append(f)
filePaths
Returns a list of the paths of the files. Can be stripped to show only the actual file name for further use by using the following code:
fileNames = []
for path in filePaths:
name = path[46:].strip()
name2 = name[:-5].strip()
fileNames.append(name2)
fileNames
where the integers (46) and (-5) can be altered depending on the file path.
In Python 3, the way it worked for me was this (respect lowercase):
from tkinter.filedialog import askopenfilenames
filenames = askopenfilenames(title = "Open 'xls' or 'xlsx' file")
for filename in filenames:
# print or do whatever you want
I hope you find it useful!
Regards!

Python Variable in tkinter window

I am building a device that counts how many parts are made off a machine and then turns the machine off at a specific number. I am using an Arduino for all the I/O work and then importing the serial data into Python as variable partCount. I would like to create a simple GUI in tkinter to show the number of parts that have been made and the total number needed. The problem is that I keep getting an error on the label lines that include a variable instead of just a text. I've done a lot of research on it, but I just can't get it for some reason. Any advice would be appreciated.
import serial
import csv
import datetime
import tkinter
#Part Variables
partNumber = "A-33693" #Part Number
stockupTotal = 10
arduinoSerialData = serial.Serial('com3',9600) #Serial Variable
now = datetime.datetime.now()
#GUI
window = tkinter.Tk()
window.title("Troy Screw Products")
titleLabel = tkinter.Label(window, text="Davenport Machine Control")
partNumberLabel = tkinter.Label(window, text="Part #:")
stockUpTotalLabel = tkinter.Label(window, text="Stockup Total:")
partCountLabel = tkinter.Label(window, text="Current Part Count:")
partNumberInfo = tkinter.Label(window, partNumber)
stockUpTotalInfo = tkinter.Label(window, stockupTotal)
partCountInfo = tkinter.Label(window, partCount)
titleLabel.pack()
partNumberLabel.pack()
partNumberInfo.pack()
stockUpTotalLabel.pack()
stockUpTotalInfo.pack()
partCountLabel.pack()
partCountInfo.pack()
window.mainloop()
#Write to CSV File
def writeCsv():
with open("machineRunData.csv", "a") as machineData:
machineDataWriter = csv.writer(machineData)
machineDataWriter.writerow([partNumber, "Stockup Complete",now.strftime("%Y-%m-%d %H:%M")])
machineData.close()
#Serial Import
while (1==1):
if (arduinoSerialData.inWaiting()>0):
partCount = arduinoSerialData.readline()
partCount = int(partCount)
if partCount == 999999:
writeCsv()
print(partCount)
There are several options you can give to a Label widget, as you can see here. You should specify all parameters after the first by name:
partNumberInfo = tkinter.Label(window, text=PartNumber)
To use Python variables in Tkinter you need to special Tk objects, of which there are four: BooleanVar, DoubleVar, IntVar, and StringVar. See this answer for a good example.
So after a ton of research over the last week, I found a solution. The problem was that the program would run the GUI, but not run the code for the serial import until the GUI window was closed. I needed a way to get both the GUI running and updated and get the serial data importing at the same time. I resolved this by creating a thread for both operations. There's probably an easier way to do this, but this what I came up with. The code is below for anyone having a similar problem.
import serial
import time
import threading
from tkinter import *
#Part Variables
partNumber = "A-33693" #Part Number
stockupTotal = 10
partCount = 0
def countingModule():
global partCount
while (1==1):
time.sleep(2)
partCount += 1
print(partCount)
def gui():
global partCount
root = Tk()
pc = IntVar()
pc.set(partCount)
titleLabel = Label(root, text="Machine Control")
partNumberLabel = Label(root, text="Part #:")
stockUpTotalLabel = Label(root, text="Stockup Total:")
partCountLabel = Label(root, text="Current Part Count:")
partNumberInfo = Label(root, text=partNumber)
stockUpTotalInfo = Label(root, text=stockupTotal)
partCountInfo = Label(root, textvariable=pc)
titleLabel.pack()
partNumberLabel.pack()
partNumberInfo.pack()
stockUpTotalLabel.pack()
stockUpTotalInfo.pack()
partCountLabel.pack()
partCountInfo.pack()
def updateCount():
pc.set(partCount)
root.after(1, updateCount)
root.after(1, updateCount)
root.mainloop()
op1 = threading.Thread(target = countingModule)
op2 = threading.Thread(target = gui)
op1.start()
op2.start()

Resources