简体   繁体   English

Tkinter从csv文件中依次读取行

[英]Tkinter reading row in order from a csv files

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. 我正在尝试为某些设备创建疑难解答,有一个输入框,使用您的关键字转到可以正常工作的正确框架,但是我需要一些帮助来从具有特定问题的csv文件读取每个单独的步骤。 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. 为此,我制作了一个按钮,可以读取csv文件中的第一步,但是,我想创建另一个名为“下一步”的按钮,该按钮每次单击时都会在csv文件中显示下一步。 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. 我尝试分配一个等于True的变量,并进行了while循环使它变为仅在变量设置为true时才显示按钮,这根本不起作用。 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): csv文件采用以下格式(仅5个步骤):

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. 如果你们能帮助我打开位于同一项目文件夹中另一个文件夹中的csv文件,我也将非常感谢。

Any help is much appreciated 任何帮助深表感谢

There are many problems with your code. 您的代码有很多问题。

You can't use .pack() and .place() in the same frame 您不能在同一框架中使用.pack().place()

Within the __init__() of the wetDevice class there are times you use .pack() and times you use .place() . wetDevice类的__init__()中,有几次您使用.pack()和一次您使用.place() So all placed elements do not show in your window. 因此,所有放置的元素都不会显示在窗口中。

Simply change those elements to either .place() or .pack() 只需将这些元素更改为.place().pack()

I have made adjustments to your code, so that it will work the way I believe you want it to. 我已经对您的代码进行了调整,以便它可以按照我认为您希望的方式工作。

  1. I changed 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 我将stepOne()更改为step() ,就像我编写代码的方式一样,只需要将一个方法更改为下一步即可
    def step():
        row = next(self.csvreader)
        test = str(row[1])
        self.instruction.configure(text=test)
        stepOneB.configure(text="Next Step")
  1. I have changed how the way your wetDevice works, it now has a self.instruction variable that is a tk.Label element, this is where the current instruction is displayed. 我已经更改了wetDevice的工作方式,它现在具有一个self.instruction变量,它是一个tk.Label元素,这是当前指令的显示位置。 I also added self.csvreader this is to hold the csv, at the current step you are at. 我还添加了self.csvreader它用于保存csv,在您当前所在的位置。
    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. 但是,我已经做出了一些假设。

  • I made it display only the last 5 instructions 我让它只显示最后5条指令

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. 不幸的是,由于我快速执行了此操作,因此我还没有完全解决您遇到错误的事实,但是现在我做了一个“ hacky”修复程序。 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". 我所做的修复是,如果尝试获取csv的下一行并导致错误,则它将禁用nextStep Button并将其文本设置为“无步骤”。

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. 您可以将csvreader添加到对象上,获取init方法中的第一行,将其添加到窗口中,并在每次按下next按钮时引用该对象。 Then you can access the csv elements one at a time and don't need to eg iterate over all rows to find row with row[0] = "1" and can pick off where you left it. 然后,您可以一次访问一个csv元素,而无需例如遍历所有行来查找具有row[0] = "1"并可以在离开它的位置进行选择。

...
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. 请记住,当csv用尽时,它将引发异常。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM