Поле ввода и метка не выровнены правильно Python 2.7 Tkinter

1

У меня есть следующее приложение Tkinter, которое в основном помогает вам настроить новую сеть, просто вставив в поле ввода новое значение. Это значение, введенное пользователем, сохраняется где-то в файле с использованием шаблона. Этот сценарий работает хорошо, но проблема в том, что я вижу поле ввода Арендатора, а не окно "Имя сетевого имени". То же самое происходит с их ярлыками. Затем, когда мы нажимаем на Add Network и получаем еще 2 окна ввода, отображаются очень странно.

Как я могу выровнять метки + поля ввода и как я могу отобразить каждую группу ярлыков + поле ввода один ниже другого?

Что-то вроде:

Арендатор [entrybox] Сеть [входная]

Арендатор [entrybox] Сеть [входная]

....................................

import Tkinter as tk

class SampleApp(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)
        self._frame = None
        self.networks = []
        self.switch_frame(StartPage)
    def switch_frame(self, frame_class):
        """Destroys current frame and replaces it with a new one."""
        new_frame = frame_class(self)
        if self._frame is not None:
            self._frame.destroy()
        self._frame = new_frame
        self._frame.pack()

class StartPage(tk.Frame):
    def __init__(self, master):
        tk.Frame.__init__(self, master)
        start_label = tk.Label(self, text="This is the start page")
        network_button = tk.Button(self, text="Create the networks", command=lambda: master.switch_frame(Networks))
        start_label.pack(side="top", fill="x", pady=10)
        deployment_button.pack()
        network_button.pack()
        subnet_button.pack()
        neutronports_button.pack()
        script_button.pack()

class Networks(tk.Frame):
    def __init__(self, master):
        tk.Frame.__init__(self, master)
        self.entries=[]
        self.create_widgets(master)
    def create_widgets(self, master):
        label = tk.Label(self, text="Insert the name of the networks")
        start_button = tk.Button(self, text="Return to start page", command=lambda: master.switch_frame(StartPage))
        new_network_button = tk.Button(self, text="Add network", command=self.add_network)
        new_network_button.bind("<Return>", self.add_network)
        new_network_button.grid(row=len(self.master.networks), column=3, padx=4, pady=6, sticky="W")
        next_button=tk.Button(self, text="Submit", command=self.networks)    
        next_button.grid(row=1500, column=5,padx=4, pady=6, sticky="W")
        label.pack(side="top", fill="x", pady=10)
        start_button.pack()
        new_network_button.pack()
        next_button.pack()
        for index, network in enumerate(self.master.networks):
            self.render_network_field(network, index)

    def add_network(self):
        requirements={'variable': tk.StringVar(self.master), 'cloudvariable': tk.StringVar(self.master)}
        if requirements: 
           self.master.networks.append(requirements)
           self.master.switch_frame(Networks)
        else: 
           tkMessageBox.showerror("tk", "No networks defined!")
           self.master.switch_frame(Networks)

    def render_network_field(self, network, index):
        labelText=tk.StringVar()
        labelText.set("Tenant name")
        labelDir=tk.Label(self,textvariable=labelText, height=4)
        labelDir.pack(side="top")
        nw_entry_field = tk.Entry(self, textvariable=network['variable'])
        nw_entry_field.grid(row=index, column=0, columnspan=2, padx=4, pady=6, sticky="NEWS")
        nw_entry_field.pack(side="right")
        labelText=tk.StringVar()
        labelText.set("Network name")
        labelDir=tk.Label(self,textvariable=labelText, height=4)
        labelDir.pack(side="top")
        cloud_entry_field = tk.Entry(self, textvariable=network['cloudvariable'])
        cloud_entry_field.grid(row=index, column=0, columnspan=2, padx=4, pady=6, sticky="NEWS")
        cloud_entry_field.pack(side="right")
        self.entries.append((network['cloudvariable'],network['variable']))

    def networks(self):
        with open("/home/dante/networks.yml", "w") as f:
             f.write("--- #" + "\n")
             for ent, cloudent in self.entries:
                    network_value=ent.get()
                    cloud_value=cloudent.get()
                    if network_value:
                      if cloud_value:
                        f.write("- { cloud: "+cloud_value+", network: "+network_value+ " }"+ "\n")

if __name__ == "__main__":
    app = SampleApp()
    app.mainloop()
  • 0
    Ошибка говорит вам, что вы пытаетесь установить опцию controller для Button , но этот виджет не имеет опцию controller . Как вы думаете, что собирается сделать Button(..., controller=self) ?
  • 0
    Вы используете controller= при создании одной из ваших кнопок, я думаю, вы хотели использовать command= : button1 = tk.Button(self, text="Next", controller=self.networks
Показать ещё 3 комментария
Теги:
button
tkinter

1 ответ

0

Ниже приведен простой код, который я только что решил решить вашу проблему. Вам просто нужно поместить функцию register() в свой класс, которая выполняется, когда вы нажимаете кнопку регистрации (помещаете ее в один класс).

import tkinter as tk
from tkinter import *

def register():
    username = x1.get()
    password = y1.get()
    if username!="" and password=="":
    file = open("accountfile.txt","a")
    file.write(username)
    file.write(" ")
    file.write(password)
    file.write("\n")
    file.close()

root=Tk()  

# String variables
x1=StringVar()
y1=StringVar()
Us=Entry(root,textvariable=x1)
Us.grid()
Ps=Entry(root, textvariable=y1)
Ps.grid() 

Reg=Button(root,text="Register",command=lambda:register())
Reg.grid()

root.mainloop()

Редактировать:

Чтобы решить вашу ошибку, сделайте глобальную переменную sa. Это определит s для всех блоков кода в файле. Кроме того, вы можете установить для него новое значение, а затем использовать новое значение в другом месте

global s
s=""

def networks(self):
    with open("/home/dante/networks.yml", "w") as f:
         f.write("--- #" + "\n")
         f.write("networks:" + "\n")
         for ent in s:
             if ent:
                f.write("- { cloud: cloud1, network: "+str(ent)+ " }"+ "\n")

def render_network_field(self, network, index):
    entry_field = tk.Entry(self, textvariable=network['variable'])
    entry_field.grid(row=index, column=0, columnspan=2, padx=4, pady=6, sticky="NEWS")
    entry_field.pack()

    global s
    s=entry_field.get()

Надеюсь это поможет

  • 0
    Спасибо за ответ, но мой код слишком сложен, чтобы применять его следующим образом. Код, который находится в вопросе, очень близок, но он не зацикливает необходимый список. Мне нужно собрать все данные в некотором списке, а затем я могу запустить цикл следующим образом.
  • 0
    Спасибо за ваш ответ. Теперь я могу обойти ошибки, но у меня нет одинакового значения для одной и той же переменной в двух разных функциях. Я попробовал это, проверив гекс (id). Есть идеи, что может быть?
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню