Tkinter从csv文件中依次读取行

时间:2019-05-17 16:28:52

标签: python python-3.x csv tkinter

我正在尝试为某些设备创建疑难解答,有一个输入框,使用您的关键字可以转到正确的框架,效果很好,但是我需要一些帮助来从具有该功能的csv文件中读取每个单独的步骤具体问题。为此,我创建了一个读取csv文件中第一步的按钮,但是,我想创建另一个名为“下一步”的按钮,该按钮每次单击时都会在csv文件中显示下一步。我也想知道如何摆脱“第一步”按钮,这样就不会造成混乱,因此很有意义。我尝试分配一个等于True的变量,并进行了while循环使它变为仅在变量设置为true时才显示按钮,这根本不起作用。任何有关如何实现此目的的想法,一切都将受到赞赏。

这是我的代码

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)  

csv文件采用这种格式(仅5个步骤):

Step, Instructions
1, instruction
2, instruction
3, instruction
4, instruction
5, instruction

如果你们能帮助我打开位于同一项目文件夹中另一个文件夹中的csv文件,我也将非常感谢。

非常感谢您的帮助

2 个答案:

答案 0 :(得分:1)

您的代码有很多问题。

  

您不能在同一帧中使用.pack().place()

__init__()类的wetDevice中,有几次您使用.pack(),也有一次您使用.place()。因此,所有放置的元素都不会显示在您的窗口中。

只需将这些元素更改为.place().pack()

  

我已经对您的代码进行了调整,以使其可以按照我认为您希望的方式工作。

  1. 我将stepOne()更改为step(),这是我编写代码的方式,您只需要使用这种方法就可以将下一步更改为
    def step():
        row = next(self.csvreader)
        test = str(row[1])
        self.instruction.configure(text=test)
        stepOneB.configure(text="Next Step")
  1. 我已经更改了wetDevice的工作方式,它现在具有一个self.instruction元素的tk.Label变量,这是当前指令的显示位置。我还添加了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
  

这是完整的工作代码,我相信它将按您的意愿工作。

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)

我已经对代码进行了调整,因此它可以按您想要的方式工作(我认为)。

但是我已经做了一些假设。

  • 我让它仅显示最后5条指令

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

答案 1 :(得分:0)

您可以将csvreader添加到对象上,获取init方法中的第一行,将其添加到窗口中,并在每次按下next按钮时引用该对象。然后,您可以一次访问一个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

请记住,当csv用尽时,它将引发异常。