将小部件放入框架内的框架时出错.Tkinter - Python3 [英] Error when putting widgets into a frame which is inside a frame. Tkinter - Python3

查看:22
本文介绍了将小部件放入框架内的框架时出错.Tkinter - Python3的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以下面的代码是我的实际代码的缩短版本.在放置在框架内的框架中显示小部件时遇到问题.

So the code below is a shortened version of what my actual code is. I'm having a problem when getting a widget to appear within a Frame which is placed within a Frame.

所以,基本上下面的代码是一个登录菜单,当点击一个按钮时,框架会变成另一个框架.在这种情况下,login_frameoverview_frame.在 overview_frame 中,我有一个名为 titleFrame 的框架,该框架位于 overview_frame 上.

So, basically the code below is a login menu, in which when a button is clicked the frame changes to another frame. In this case login_frame to overview_frame. Within the overview_frame i have a another frame called titleFrame, this frame is placed on the overview_frame.

现在,当我想将小部件放入 titleFrame 中时出现问题,在此实例中,titleLabel 使用 .grid() 方法位置.

Now the problem occurs when i want to put a widget into the titleFrame in this instance the titleLabel with the .grid() method of placement.

我已经用我创建的其他 tkinter 应用程序完成了这项工作,我已经尝试了好几个小时来解决这个问题,但没有得出结论.这是我不断收到的错误:

I have done this with other tkinter applications i have created, i've been trying to suss this out for a good few hours now and not come to a conclusion. This is the error i keep getting:

Traceback (most recent call last):
  File "C:\Users\nasto\Documents\Company\rfr.py", line 67, in <module>
    app = frame_store()
  File "C:\Users\nasto\Documents\Company\rfr.py", line 16, in __init__
    frame = n_frame(parent=container, controller=self)
  File "C:\Users\nasto\Documents\Company\rfr.py", line 57, in __init__
    titleLabel = tk.Label(titleFrame, text='TITLE').grid(row=0,column=0, sticky='nsew', padx=2, pady=2)
  File "C:\Users\nasto\AppData\Local\Programs\Python\Python36-32\lib\tkinter\__init__.py", line 2220, in grid_configure
    + self._options(cnf, kw))
_tkinter.TclError: cannot use geometry manager grid inside . which already has slaves managed by pack

现在此代码与我制作的其他应用程序之间的唯一区别是 frame_store 类.其中有一行代码使用了 .Pack() 但是当删除它时 login_frametitleFrame 不显示并且小部件直接到 overview_frame.我怎么可能摆脱 .Pack() 同时确保所有帧仍然可见,或者将 titleLabel 放在 titleFrame 上> 使用 .grid() 时我个人认为这可能与 titleFrame 与 eg//self 的关联有关,但是在处理这个问题的同时,我还没有得到有效的结果.

Now the only difference between this code and the other applications i have made is the frame_store class. In which there is one line of code that used .Pack() However when removing this the login_frame and titleFramedo not show and the widget goes directly onto the overview_frame. How would i possibly get rid of the .Pack() while ensuring that all frames should still be visible, or to place the titleLabel on the titleFrame while using .grid() I personally think it may be to do with what the titleFrame is connected with eg// self but while messing around with that i have not been getting the result that works.

import tkinter as tk
import hashlib
import sqlite3

class frame_store(tk.Tk):
  def __init__(self, *args, **kwargs):
    tk.Tk.__init__(self, *args, **kwargs)
    '''container is used so that all the frames can be stacked, from there we can call other frames within the container to the top, to the current active frame'''
    container = tk.Frame(self)
    container.pack(side='top', fill='both', expand=True)
    container.grid_rowconfigure(0, weight=1)
    container.grid_columnconfigure(0, weight=1)
    self.frames = {}
    for n_frame in (login_frame, overview_frame, accounting_frame):
      pageName = n_frame.__name__
      frame = n_frame(parent=container, controller=self)
      self.frames[pageName] = frame
      frame.grid(row=0, column=0, sticky='nsew')
    self.show_frames('login_frame')

  def show_frames(self, pageName):
    frame = self.frames[pageName]
    self.update_idletasks()
    self.state('zoomed')
    self.title('A2 Project')
    frame.tkraise()

class login_frame (tk.Frame):
  def __init__(self, parent, controller):
    tk.Frame.__init__(self, parent)
    self.controller = controller
    loginButton = tk.Button(self, text='Login', command = self.no_credentials).grid(row=3,column=0)
    self.controller.bind('<Control-n>', lambda event: self.no_credentials())

  def no_credentials(self):
    self.controller.show_frames('overview_frame')

  def clear(self):
    self.__userID.set('')
    self.__password.set('')

  def exit(self):
    app.destroy()   


class overview_frame(tk.Frame):
  def __init__(self, parent, controller):
    tk.Frame.__init__(self, parent)
    self.controller = controller

    self.config(background='#000000')  
    self.rowconfigure(0, weight=1)
    self.columnconfigure(0, weight=1)

    titleFrame = tk.Frame(self, background='#f8f8ff', bd=1, relief='sunken').grid(row=0, column=0, sticky='nsew', padx=2, pady=2)

    titleLabel = tk.Label(titleFrame, text='TITLE').grid(row=0,column=0, sticky='nsew', padx=2, pady=2)


class accounting_frame(tk.Frame):
  def __init__(self, parent, controller):
    tk.Frame.__init__(self, parent)
    self.controller = controller
  pass

if __name__ == "__main__":
    app = frame_store()
    app.mainloop()

推荐答案

您的问题是由于创建您的框架并在一行代码中对齐.

Your problem is due to creating your frame and aligning it in a single line of code.

写作时:

titleFrame = tk.Frame(self, relief='sunken').grid(row=0, column=0)

titleFrame.grid() 方法的输出,而不是您刚刚创建的 tk.Frame.所以它不能用作未来小部件的父级.

titleFrame is the output of the .grid() method, instead of the tk.Frame you just created. So it cannot be used as a parent for future widgets.

为了保持对小部件的引用,您必须将小部件创建与小部件对齐分开:

In order to keep the reference to a widget, you have to separate widget creation from widget alignment:

titleFrame = tk.Frame(self, background='#f8f8ff', bd=1, relief='sunken')
titleFrame.grid(row=0, column=0, sticky='nsew', padx=2, pady=2)
titleLabel = tk.Label(titleFrame, text='TITLE')
titleLabel.grid(row=0,column=0, sticky='nsew', padx=2, pady=2)

这篇关于将小部件放入框架内的框架时出错.Tkinter - Python3的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆