I wrote an app using that basis learned there, and this app reads a text file and removes the redundant lines, and returns a list of numbers. The code below returns a list of numbers in PageOne
, But as I want to use that list in PageTwo
, it changes to a string. I know I have initially introduced variables as strings, but it does not work under other types as well. How I can keep that as a list?
To run this code you can put a few numbers with space separation in a text file and open it using the app.
import tkinter as tk
from tkinter import filedialog
class Data:
def __init__(self):
self.Tot_grids = tk.IntVar()
self.NO = tk.StringVar()
self.NEW = tk.StringVar()
self.NEW2 = tk.StringVar()
class SampleApp(tk.Tk):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.geometry("500x200")
container = tk.Frame(self)
container.pack()
self.data = Data()
self.frames = {}
for F in (PageOne, PageTwo):
frame = F(container, self.data)
self.frames[F] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.frames[PageOne].button2.config(command=self.go_to_page_two)
self.show_frame(PageOne)
def go_to_page_two(self):
self.show_frame(PageTwo)
def show_frame(self, c):
frame = self.frames[c]
frame.tkraise()
class PageOne(tk.Frame):
def __init__(self, parent, data):
super().__init__(parent)
self.data = data
def opentext():
my_file = filedialog.askopenfilenames(initialdir="/pycharm", title="Select your file")
for T in my_file: # this line should be here when opening multiple files
import re
with open(T, 'r') as infile1:
lines = infile1.read()
nums = []
for n in re.findall(r'(\d \.\d |\d \*\d )', lines):
split_by_ast = n.split("*")
if len(split_by_ast) == 1:
nums = [float(split_by_ast[0])]
else:
nums = [float(split_by_ast[1])] * int(split_by_ast[0])
nums = nums[1:len(nums)]
data.NO.set(nums)
label3.config(text=nums)
label4.config(text=type(nums))
self.button1 = tk.Button(self, text="Open file(s)", command=opentext)
self.button1.grid(row=0, column=0, columnspan=2, pady=20)
label1 = tk.Label(self, text="imported numbers:")
label1.grid(row=1, column=0, pady=10)
label2 = tk.Label(self, text="type of imported numbers:")
label2.grid(row=2, column=0, pady=5)
label3 = tk.Label(self)
label3.grid(row=1, column=1)
label4 = tk.Label(self)
label4.grid(row=2, column=1, pady=5)
self.button2 = tk.Button(self, text="Continue")
self.button2.grid(row=3, column=0, columnspan=2, pady=10)
class PageTwo(tk.Frame):
def __init__(self, parent, data):
super().__init__(parent)
self.data = data
self.label5 = tk.Label(self, textvariable=self.data.NEW)
self.label5.pack()
self.label5 = tk.Label(self, textvariable=self.data.NEW2)
self.label5.pack()
self.data.NO.trace_add('write', self.on_grids_updated)
def on_grids_updated(self, *args):
self.data.NEW.set(self.data.NO.get())
self.data.NEW2.set(type(self.data.NO.get()))
app = SampleApp()
app.mainloop()
I also wondered why the type of list in PageOne is shown with some random numbers? thanks
CodePudding user response:
You can use Variable
which is the base class of StringVar
, IntVar
, etc.
Variable.get()
does not convert the stored data like StringVar.get()
or IntVar.get()
. However it seems that list
will be converted to tuple
by TCL internally.
class Data:
def __init__(self):
self.Tot_grids = tk.IntVar()
self.NO = tk.Variable() # used Variable instead of StringVar
self.NEW = tk.StringVar()
self.NEW2 = tk.StringVar()
Also change the line
label4.config(text=type(nums))
to
label4.config(text=str(type(nums)))
will show the type correctly.