tkinter将按钮附加到canvas命令

时间:2015-10-28 14:36:37

标签: tkinter tkinter-canvas

我试图让命令在现有按钮下添加/添加新按钮以打开像blender style gui这样的新窗口?

from tkinter import*
from tkinter import ttk
import tkinter as tk
#creating frame to basic window, add scrollbar to canvas and background image
class mainWindow:
    def __init__(self, master):
    frame = ttk.Frame(master).pack(fill=X)
    cv = tk.Canvas(frame, scrollregion=(0,0,270,2750), height=2800, width=270, bg = "cyan")
    self.image1 = PhotoImage(file="logoQs270x700.png")
    image = cv.create_image(0, 0, anchor = NW, image=self.image1)
    scb = tk.Scrollbar(frame, command=cv.yview)
    cv.pack(side=LEFT)
    scb.pack(side=RIGHT, fill=Y)
    cv.configure(yscrollcommand=scb.set)

    a='white'
    b='purple'
    c=22
    f = 'Neuropol'
    g = GROOVE
    h = 'violet'
    #basic button     
    btn1 = tk.Button(frame, text = "Site Prep", fg = a, anchor = W, font = f)
    btn1.configure(width = c, activebackground = h, relief = g, bg = b)
    btn1_window = cv.create_window(5, 5, anchor=NW, window=btn1)     

#basic window
root = tk.Tk()
root.title('Built Up Rates')
root.geometry('280x700+0+0')
A=mainWindow(root)
root.mainloop()

这个想法是当点击它打开时,有一个像标题一样的按钮 在它下面的子标题并向下移动它下面的现有按钮 如果再次单击相同的按钮,它会向上移动标题按钮并隐藏 子标题或子标签..     [徽标图片] [1]     [搅拌机Gui样品未激活] [2]     [激活时的搅拌器Gui样本] [3]

  [1]: http://i.stack.imgur.com/6pDeu.png
  [2]: http://i.stack.imgur.com/qUDPb.png
  [3]: http://i.stack.imgur.com/CPeuA.png

4 个答案:

答案 0 :(得分:0)

我的建议是使用框架而不是画布。使用框架,您可以使用pack,它擅长从上到下堆叠小部件。您无需进行任何计算即可将小部件放置在正确的位置。

小部件中的每个部分都应该是一个框架,然后您只需将它们从上到下打包。在该部分中,您需要两个小部件:标题的标签和内容的框架。打开和关闭该部分只需要在内部框架上调用packpack_forget

使用面向对象的方法

由于python是面向对象的,因此您应该将每个可扩展部分视为一个对象。您的GUI整体上变成了从上到下堆叠的这些对象的集合。我们可以创建一个负责展开/折叠机制的基类,子类可以添加它们需要在框架内显示的任何小部件。

基类

让我们从可扩展框架的基类开始。我们将创建用于打开或关闭框架的小部件,并且我们将创建一个内部框架来保存按钮和属于该框架的其他东西。我们将添加一个分隔符,以模仿您问题中屏幕截图的外观。

import Tkinter as tk
import ttk

class ExpandoFrame(tk.Frame):
    closed_glyph = u"\u25b6"
    opened_glyph = u"\u25bc"

    def __init__(self, parent, title):
        tk.Frame.__init__(self, parent, borderwidth=0)
        self.title = title

        self.sep = ttk.Separator(self, orient="horizontal")
        self.header = tk.Label(self, width=20, anchor="w")
        self.inner = tk.Frame(self)

        self.sep.pack(side="top", fill="x")
        self.header.pack(fill="x", padx=4)

        self.collapse()

        self.header.bind("<1>", self.toggle)

这个类有三个方法:一个用于显式扩展该部分,一个用于显式地折叠它,另一个用于从一个切换到另一个。

    def toggle(self, event=None):
        if self.closed_glyph in self.header.cget("text"):
            self.expand()
        else:
            self.collapse()

    def expand(self):
        self.header.configure(text="%s %s" % (self.opened_glyph, self.title))
        self.inner.pack(side="top", fill="both", expand=True)

    def collapse(self):
        self.header.configure(text="%s %s" % (self.closed_glyph, self.title))
        self.inner.pack_forget()

子类化“ExpandoFrame”

这为我们奠定了基础。现在,每个子类都可以在内部框架中放置它想要的任何小部件。以下是几个例子:

class SectionSitePrep(ExpandoFrame):
    def __init__(self, parent):
        ExpandoFrame.__init__(self, parent, "Site Preparation")

        self.cb1 = tk.Checkbutton(self.inner, text="Choose this")
        self.cb2 = tk.Checkbutton(self.inner, text="Or this")
        self.cb1.pack(side="top", anchor="w")
        self.cb2.pack(side="top", anchor="w")

class SectionWblff(ExpandoFrame):
    def __init__(self, parent):
        ExpandoFrame.__init__(self, parent, "WBLFF")

        self.rbvar = tk.StringVar(value=1)
        self.rb1 = tk.Radiobutton(self.inner, text="One", variable=self.rbvar, value=1)
        self.rb2 = tk.Radiobutton(self.inner, text="Two", variable=self.rbvar, value=2)
        self.rb3 = tk.Radiobutton(self.inner, text="Three", variable=self.rbvar, value=3)
        self.rb1.pack(side="left")
        self.rb2.pack(side="left")
        self.rb3.pack(side="left")

全部放在一起

最后,你可以将这些部分从上到下放在一个pack的框架中:

class Example(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, parent)

        s1 = SectionSitePrep(self)
        s2 = SectionWblff(self)

        s1.pack(side="top", fill="x")
        s2.pack(side="top", fill="x")

答案 1 :(得分:0)

from tkinter import*

def subT1():

    def destF1a():
        frame1a.destroy()

    frame1a = Frame(frame1)
    frame1a.grid(in_=frame1, row = 0)

    btn1=Button(text = 'Title1', bg = 'yellow', width = w, command=destF1a)
    btn1.grid(in_=frame1a, row = 0)

    btn1a=Button(text = 'Subtitle1', width = w)
    btn1a.grid(in_=frame1a, row = 1)

    btn1b=Button(text = 'Subtitle2', width = w)
    btn1b.grid(in_=frame1a, row = 2,)

def subT2():

    def destF2a():
        frame2a.destroy()

    frame2a = Frame(frame2)
    frame2a.grid(in_=frame2, row = 0)

    btn1=Button(text = 'Title2', bg = 'yellow', width = w, command=destF2a)
    btn1.grid(in_=frame2a, row = 0)

    btn1a=Button(text = 'Subtitle1', width = w)
    btn1a.grid(in_=frame2a, row = 1)

    btn1b=Button(text = 'Subtitle2', width = w)
    btn1b.grid(in_=frame2a, row = 2,)

root = Tk()
w= 23

mainFrame = Frame(root)
mainFrame.pack(fill=X)

frame1 = Frame(mainFrame)
frame1.pack(in_=mainFrame, fill=X)

tt1=Button(text='Title1', width = w ,bg = 'green',command = subT1)
tt1.grid(in_=frame1, row=0)

frame2 = Frame(mainFrame)
frame2.pack(in_=mainFrame, fill=X)

tt2=Button(text='Title2', width = w ,bg = 'green',command = subT2)
tt2.grid(in_=frame2, row=0)

root.mainloop()

简单且有效;)通过作弊..它与同一帧中的现有按钮重叠并打开按钮的新命令..使用包,网格和帧销毁

答案 2 :(得分:0)

from tkinter import*

def subT1():

    def destF1a():
        frame1a.destroy()

    frame1a = Frame(frame1)
    frame1a.grid(in_=frame1, row = 0)

    btn1=Button(text = 'Title1', bg = 'yellow', width = w, command=destF1a)
    btn1.grid(in_=frame1a, row = 0)

    btn1a=Button(text = 'Subtitle1', width = w)
    btn1a.grid(in_=frame1a, row = 1)

    btn1b=Button(text = 'Subtitle2', width = w)
    btn1b.grid(in_=frame1a, row = 2,)

def subT2():

    def destF2a():
        frame2a.destroy()

    frame2a = Frame(frame2)
    frame2a.grid(in_=frame2, row = 0)

    btn1=Button(text = 'Title2', bg = 'yellow', width = w, command=destF2a)
    btn1.grid(in_=frame2a, row = 0)

    btn1a=Button(text = 'Subtitle3', width = w)
    btn1a.grid(in_=frame2a, row = 1)

    btn1b=Button(text = 'Subtitle4', width = w)
    btn1b.grid(in_=frame2a, row = 2,)

root = Tk()
root.title('Test')
root.geometry('+0+0')
w= 23

mainFrame = Frame(root)
mainFrame.pack(fill=X)

frame1 = Frame(mainFrame)
frame1.pack(in_=mainFrame, fill=X)


tt1=Button(text='Title1', width = w ,bg = 'green',command = subT1)
tt1.grid(in_=frame1, row=0)

frame2 = Frame(mainFrame)
frame2.pack(in_=mainFrame, fill=X)

tt2=Button(text='Title2', width = w ,bg = 'green',command = subT2)
tt2.grid(in_=frame2, row=0)

root.mainloop()

这实际上有效。扩展风格tittle ..通过作弊..重叠技术现有主要按钮在框架中,使用pack,grid和frame.destroy()并使用新命令,从而附加所需按钮:)

答案 3 :(得分:0)

from tkinter import*
import tkinter as tk

def subT1():
    def destF1a():
        frame1a.destroy()

    frame1a = tk.Frame(frame1)
    frame1a.grid(in_=frame1, row = 0)

    btn1=tk.Button(text = 'Site Preparation', bg = e, width = w,relief = r, fg=d, font = g,command=destF1a)
    btn1.grid(in_=frame1a, row = 0)

    btn1a=tk.Button(text = 'Site Clearence', width = w, bg=f,font = g,relief = s)
    btn1a.grid(in_=frame1a, row = 1)

def subT2():
    def destF2a():
        frame2a.destroy()

    frame2a = tk.Frame(frame2)
    frame2a.grid(in_=frame2, row = 0)

    btn2=tk.Button(text = 'Piling Works', bg = e, width = w,relief = r, fg=d, font = g,command=destF2a)
    btn2.grid(in_=frame2a, row = 0)

    btn2a=tk.Button(text = 'Supply', width = w, font = g,bg=f, relief = s)
    btn2a.grid(in_=frame2a, row = 1)

root=Tk()
root.title('Built Up Rates')
root.geometry("240x600+0+0")
mainCv=Canvas(root,scrollregion= 0,0,225,2750),height=800,width=225,bg='white')
scb=Scrollbar(root,command=mainCv.yview)
mainCv.pack(side=LEFT)
scb.pack(side=RIGHT,fill=Y)
mainCv.configure(yscrollcommand=scb.set)

w=25
w1 = 5
r= RIDGE
s= GROOVE
c='purple'
d='white'
e='dark violet'
f='yellow'
g = ('Comic Sans MS', 10, 'bold', 'italic')

mainFrame=tk.Frame(root)
mainFrame_window=mainCv.create_window(5,5,anchor=NW,window=mainFrame)

frame1 = tk.Frame(mainFrame)
frame1.pack(in_=mainFrame, fill=X)

tt1=tk.Button(text='Site Preparation', width = w ,bg = c,fg=d, relief = r, font = g,command = subT1)
tt1.grid(in_=frame1, row=0)

frame2 = tk.Frame(mainFrame)
frame2.pack(in_=mainFrame, fill=X)

tt2=tk.Button(text='Piling Works', width = w ,bg = c,fg=d,relief = r, font = g,command = subT2)
tt2.grid(in_=frame2, row=0)   

root.mainloop()

就像画布上的魅力一样:)