Reputation: 67
I am trying to create a troubleshooter for some devices, there is an entry box which uses your keyword to go to the correct frame which works fine, but i need some help to read each separate step from the csv file which has that specific problem. To do this, i made a button which reads the first step in the csv file, however, i want to make another button called "Next Step", which displays the next step in the csv file every time it's clicked. I also would like to know how i can get rid of the "First Step" button so there is no confusion and so that it makes sense. I have tried assigning a variable equal to True and made a while loop to make it so the button only displays when the variable is set to true, which didn't work at all. Any ideas on how to make this work, everything is much appreciated.
Here is my code
class wetDevice(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
label = tk.Label(self, text="How to fix a wet phone", fg="purple", font=controller.title_fontT)
label.pack(side="top", fill="x", pady=10)
def stepOne():
with open("Wet Device.csv", "r") as f:
csvreader = csv.reader(f, delimiter=",")
for row in csvreader:
if "1" in row[0]:
test = str(row[1])
stepOneL = tk.Label(self, text=test)
stepOneL.place(x = 10, y = 70, width = 500, height = 20)
#def nextStep():
stepOneB = tk.Button(self, text="First Step",
command=lambda: stepOne())
stepOneB.place(x = 230, y = 130, width = 60, height = 20)
mButton = tk.Button(self, text="Go to the Main Troubleshoot Menu",
command=lambda: controller.show_frame("MainTMenu"))
mButton.place(x = 285, y = 210, width = 200, height = 25)
the csv file is in this format(with only 5 steps):
Step, Instructions
1, instruction
2, instruction
3, instruction
4, instruction
5, instruction
I also would really appreciate it if you guys could help me out with opening the csv file which is in another folder in the same project folder.
Any help is much appreciated
Upvotes: 0
Views: 1089
Reputation: 815
There are many problems with your code.
You can't use
.pack()
and.place()
in the same frame
Within the __init__()
of the wetDevice
class there are times you use .pack()
and times you use .place()
. So all placed elements do not show in your window.
Simply change those elements to either .place()
or .pack()
I have made adjustments to your code, so that it will work the way I believe you want it to.
stepOne()
to just be step()
, the way I have written the code you will only need this one method for changing the to the next step def step():
row = next(self.csvreader)
test = str(row[1])
self.instruction.configure(text=test)
stepOneB.configure(text="Next Step")
self.instruction
variable that is a tk.Label
element, this is where the current instruction is displayed. I also added self.csvreader
this is to hold the csv, at the current step you are at. def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
label = tk.Label(self, text="How to fix a wet phone", fg="purple")
label.pack(side="top", fill="x", pady=10)
self.instruction = tk.Label(self, text="", fg="purple") # the new instruction Label
self.instruction.pack()
f = open("Wet Device.csv", "r")
self.csvreader = csv.reader(f, delimiter=",") # new csv element
Here is the full working code, that I believe will work as you want.
import tkinter as tk
import csv
class wetDevice(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
label = tk.Label(self, text="How to fix a wet phone", fg="purple", font=controller.title_fontT)
label.pack(side="top", fill="x", pady=10)
self.instructions_frame = tk.Frame(self)
self.instructions_frame.place(x = 230, y = 55)
self.instruction_labels = []
f = open("Wet Device.csv", "r")
self.csvreader = csv.reader(f, delimiter=",")
def step():
try:
row = next(self.csvreader)
test = str(row[1])
if len(self.instruction_labels) >= 5:
temp = self.instruction_labels.pop(0)
temp.destroy()
instruction_temp = tk.Label(self.instructions_frame, text=test, fg="black")
instruction_temp.pack()
self.instruction_labels.append(instruction_temp)
stepOneB.configure(text="Next Step")
except StopIteration:
stepOneB.configure(state="disabled", text="No Steps")
# def nextStep():
stepOneB = tk.Button(self, text="First Step", fg="green",
command=lambda: step())
stepOneB.place(x=230, y=175, width=60, height=20)
mButton = tk.Button(self, text="Go to the Main Troubleshoot Menu",
command=lambda: controller.show_frame("MainTMenu"))
mButton.place(x=285, y=210, width=200, height=25)
I have made adjustments to the code so it will work as you wanted (I think).
I have made some assumptions of my own however.
And unfortunately since I did this quickly I haven't completely fixed the fact you get an error, however I made a "hacky" fix for now. The fix I made was that if it attempts to get the next row of the csv and it causes an error then it will disable the nextStep
Button
and set its text to "No Steps".
Upvotes: 1
Reputation: 1894
You could add the csvreader onto the object, get the first line within the init mithod, add it to the window and reference the object each time you press the next-button. Then you can access the csv elements one at a time and don't need to e.g. iterate over all rows to find row with row[0] = "1"
and can pick off where you left it.
...
self.csvreader = csv.reader(f, delimiter=",")
data = next(self.csvreader)
# set text with data
...
def nextStep():
data = next(self.csvreader)
# change text with data
Keep in mind that, when the csv is exhausted, it will raise an exception.
Upvotes: 0