首页 > 解决方案 > 使用按钮 Tikinter python 3 传递输入

问题描述

我是 python 新手,这是我的第一个代码。我的目标是制作可编辑的表我使用了两个类我的主要类的目标是将多个名称打印到一个表中:

from tkinter import *
from tabels import *

class Improved():

    def __init__(self, data):
            self.data = data
            self.root = Tk()
            self.entry = []
            self.Grid_buttom()
            self.text()
            self.root.mainloop()

    def Grid_buttom(self):
        x = ['Name', 'Last name', 'Numbers']
        for i in range(3):
            Label(self.root, text=x[i], borderwidth=1, bg='white', relief='solid', fg='Black',
                  font="Times 13 bold", height=1, width=11).grid(column=i, row=0)

        for i, item in enumerate(self.data):
            Button(self.root, text=(self.data[i][0]), command=lambda: self.Command(i), height = 1, width = 15).grid(column=0, row=i+1)
    def text(self):
        '''text infront of bottoms'''
        for i, item in enumerate(self.data):
            Label(self.root, text=self.data[i][1],borderwidth=1,bg='white',relief='solid',fg='Black',
                  font="Times 13 bold", height = 1, width = 11   ).grid(column=1, row=i+1)
            Label(self.root, text=self.data[i][2], borderwidth=1, bg='white', relief='solid', fg='Black',
                  font="Times 13 bold", height=1, width=11).grid(column=2, row=i+1)

    def Command(self,i):
        self.data[i]=inside_Tables(self.data[i])

x = [['alireza', '2', '3'], ['amir', '5', '6'], ['hossein', '8', '9'],
         ['hamidreza', 'aghamiri', '09126993613'],
         ['hamidreza', 'aghamiri', '09126993613']]  # dar daste aval size colomn ha ham neveshte shode

y = Improved(x)

我的第二堂课将通过单击来编辑主表的每一列

from tkinter import *

class inside_Tables():


    def __init__(self, data):
     self.data=data
     self.root=Tk()
     self.entry=[]
     self.Grid()
     self.Buttom()
     self.root.mainloop()
    def Grid(self):
        '''it defines grids Of our TK ..include our rows and columns'''
        k = 0
        for i in range(len(self.data)):
                v = StringVar(self.root, value=self.data[i])
                self.entry.append(Entry(self.root, textvariable=v))
                self.entry[k].grid(row=1, column=i)
                k = k + 1

    def Buttom(self):
        Button(self.root, text="Save", command=lambda: self.Command(),height=1, width=11).grid(row=2, column=int(len(self.data)/2)-1,sticky=NSEW)
    def Command(self):
        xx = []
        y = []
        output = []
        for i in range(len(self.entry)):
            output.append(self.entry[i].get())
        for j in range(len(self.data)):
            xx.append(output[j])
        y.append(xx)
        self.new_data=y
        self.root.destroy()

问题:

当我单击每一列进行编辑时,它总是传递一列 i=4 我想传递我单击它的右列

我的第二个问题是当我点击保存更改主要数据并更正它时我想这样做..有什么解决方案吗?

标签: pythonpython-3.xtkinter

解决方案


首先,对您的代码提出一些建设性的意见:

  1. 请使您的代码行少于 80 个字符以提高可读性。

    • 一个列表总是可以显示在多行上。前任:

    x = [['alireza', '2', '3'], ['amir', '5', '6'], ['hossein', '8', '9'], ['hamidreza', 'aghamiri', '09126993613'], ['hamidreza', 'aghamiri', '09126993613']] # dar daste aval size colomn ha ham neveshte shode

变成:

x = [
    ['alireza', '2', '3'], 
    ['amir', '5', '6'], 
    ['hossein', '8', '9'], 
    ['hamidreza', 'aghamiri', '09126993613'], 
    ['hamidreza', 'aghamiri', '09126993613']
    ]# dar daste aval size colomn ha ham neveshte shode
  • 当您定义小部件属性时:如果您点击了行尾,只需将定义拆分为 1 / 行以获得更好的可读性,或者至少按 Enter 以开始新的定义行......在后一种情况下,不要t width=1width = 1例如:

        for i, item in enumerate(self.data):
        Button(self.root, text=(self.data[i][0]), command=lambda: self.Command(i), height = 1, width = 15).grid(column=0, row=i+1)
    

变成:

        for i, item in enumerate(self.data):
            Button(self.root, 
                text=(self.data[i][0]), 
                command = lambda: self.Command(i), 
                height = 1, width = 15).grid(column = 0, row = i + 1)

您的第一个问题是 lambda 问题;每次您的循环将其传递给您的小部件时:

                command = lambda: self.Command(i), 

它使它改变其他小部件。要使其动态化,请使用 lambda 变量“x”并将其分配为“i”,然后将“x”传递给您的 self.Command:这将使您的所有小部件都识别它自己的“i”

                command = lambda x = i: self.Command(x), 

你的另一个问题:

  1. inside_Tables 不会与您的主窗口通信,它会更改类范围内的数据,但不会更改作为另一个类的主应用程序中的数据。
  2. 我还认为您的按钮/标签每个都可以由另一个类表示,这将允许您使其包含自己的数据,而不必担心其余部分。

我已经修改了下面的代码以使其工作(有些东西现在没用了,我建议清理一下),现在你只需要一个文件,我相信你的第二部分代码暗示了另一个名为 tabels.py 的文件,我将其包含在主代码中。

更改:而不是from tkinter import * 你的程序现在使用 import tkinter as tk 来更好地理解你在做什么。在您的代码中使用 Button 或 Entry 时,现在它使用 tk.Button、tk.Entry、tk.Tk 和 tk.StringVar,因此您知道它们来自 tkinter。

类:

  1. 添加了 TableRow :此类管理来自“x”的每个数据条目,其中包含您的主要数据。
  2. 改进:净化版本,这现在是你的主应用程序,我让它继承自 tk.Tk,以便在你调用它时绘制窗口。
  3. inside_Tables :经过净化的版本,因此它通过 master 和 tkinter stringvars 与您的主应用程序通信。

如果您有任何问题,请发表评论。

import tkinter as tk
#from tabels import * # I guess both classes were coded in different files?

class TableRow(tk.Frame):
    ''' Making each data row an object for better use of data. '''
    def __init__(self, master, i):
        tk.Frame.__init__(self, master)

        self.data = master.data[i]

        self.command_text = tk.StringVar(value=self.data[0])
        self.label1_text = tk.StringVar(value=self.data[1])
        self.label2_text = tk.StringVar(value=self.data[2])

        self.grid()

        button = tk.Button(self, 
            #text=self.data[0], 
            textvariable=self.command_text,
            command=lambda x=i: self.Command(x),
            width=11)
        button.grid(column=0, row=0)

        label = tk.Label(self, 
            #text=self.data[1], 
            textvariable=self.label1_text,
            borderwidth = 1, bg = 'white', relief = 'solid',
            fg = 'black', font = 'times 13 bold', height = 1,
            width = 11)
        label.grid(column=1, row=0)
        label = tk.Label(self, 
            #text = self.data[2], 
            textvariable=self.label2_text,
            borderwidth = 1, bg = 'white', relief = 'solid', fg = 'black',
            font = 'times 13 bold', height = 1, width=11)
        label.grid(column=2, row=0)

    def Command(self, i):
        inside_Tables(self, i)

class Improved(tk.Tk): 
    def __init__(self, data):
        tk.Tk.__init__(self)
        self.data = data
        #self.entry = [] #Not used in this class.
        #self.Grid_buttom()
        self.grid()
        #self.text()

    def grid(self):
        topframe = tk.Frame(self)
        topframe.grid()
        x = ['Name', 'Last name', 'Numbers']
        for i in x:
            tk.Label(topframe, 
                text=i, borderwidth=1, bg='white', 
                relief='solid', fg='Black',
                font="Times 13 bold", height=1, 
                width=11).grid(column=x.index(i), row=0)

        for i, item in enumerate(self.data):
            TableRow(self, i)

class inside_Tables():
    def __init__(self, master, i):
        self.master = master
        self.data=self.master.data
        self.root=tk.Tk()
        self.entry=[]
        self.Grid()
        self.Buttom()

        self.root.mainloop()
    def Grid(self):
        '''it defines grids Of our TK ..include our rows and columns'''
        k = 0
        for i in range(len(self.data)):
            v = tk.StringVar(self.root, value=self.data[i])
            self.entry.append(tk.Entry(self.root, textvariable=v))
            self.entry[k].grid(row=1, column=i)
            k = k + 1 

    def Buttom(self):
        tk.Button(self.root, 
            text="Save", command=self.Command,
            height=1, width=11).grid(row=2, column=int(len(self.data)/2)-1,
                    sticky='NSEW')
    def Command(self):
        xx = []
        #y = [] #now useless
        output = []
        for i in range(len(self.entry)):
            output.append(self.entry[i].get())
        for j in range(len(self.data)):
            xx.append(output[j])

        #y.append(xx)
        #self.new_data=y
        self.master.command_text.set(xx[0])
        self.master.label1_text.set(xx[1])
        self.master.label2_text.set(xx[2])

        self.root.destroy()

x = [ 
    ['alireza', '2', '3'], 
    ['amir', '5', '6'], 
    ['hossein', '8', '9'], 
    ['hamidreza', 'aghamiri', '09126993613'], 
    ['hamidreza', 'aghamiri', '09126993613']
    ]  # dar daste aval size colomn ha ham neveshte shode

#y = Improved(x) # Removed, included below to make program standalone.

if __name__ == '__main__':
    y = Improved(x)
    y.mainloop()

推荐阅读