Wirror 发表于 2021-7-20 12:44:39

bind

# 这段代码绑定Enter键触发的事件为ok,为什么窗口打开后还没按下回车ok就被调用了(代码从front_sell进入的,没有其他问题),
而且为什么在ok函数中没法get文本框的字符呢?
另:写在类中的方法中参数event和master是干什么用的,一直没有弄明白

from tkinter import *
class Application_ui(Frame):
    def __init__(self, master=None):
      Frame.__init__(self, master)
      self.master.title('Form1')
      self.master.geometry('1424x862')
      self.createWidgets()


    def createWidgets(self):
      self.top = self.winfo_toplevel()

      self.style = Style()
      front_sell_window.bind('<KeyPress-Return>', self.ok())

class Application(Application_ui):
    #这个类实现具体的事件处理回调函数。界面生成代码在Application_ui中。
    def __init__(self, master=None):
      Application_ui.__init__(self, master)

    def ok(self):# todo 按下回车后的操作:
      aaa = 'aaa'
      print(aaa)
def front_sell(t):
    global front_sell_window
    front_sell_window = Tk()
    global top
    top = t
    front_sell_window.protocol('WM_DELETE_WINDOW', me_quit)
    Application(front_sell_window).mainloop()

阿奇_o 发表于 2021-7-20 16:07:28

本帖最后由 阿奇_o 于 2021-7-20 16:17 编辑

先吐槽:这是谁教的代码,感觉乱得很,用了OOP还用global变量? 一个简单的GUI程序,搞两个类,有必要?

正经回答:
master, 通常对应着 slave ,即 主人-侍从/奴隶/从动装置
在GUI这里相当于 每个组件widget都需要从属于一个master,这个"主人" 相当于是它所处的周围环境(外部环境),
比如lb = Label(master=xFrame, ...),当xFrame的行列配置,背景颜色等属性改变时,就相当于 其内部组件 lb 所处的外部环境发生了改变。
又比如,lb.pack()了,但 它的master 没有 pack()/grid()/place() ,那 lb 就跟着 其xFrame 不可见了(隐藏着)。

event 说白了,就是一个 循环,一个循环事件,什么事件呢?——就是 不断检查鼠标、键盘等输入设备,是否有输入(是否有某个特定的输入)。
将特定的事件绑定(event binding),意思是:对这一特定事件(如鼠标右键是否被按下)进行判断。
通常写法是: the_widget.bind("<Button-3>", xfunc)   即 the_widget 该组件激活时,检查鼠标右键是否被按下,是,就触发执行xfunc函数

但GUI编程通常会用OOP,不然可能要到处声明 global 变量。
所以 通常 写self.widget.bind("<Button-3>", lambda e: self.xfunc(e, ...) )
这时self.xfunc带有event参数,可用在 比如我要判断鼠标右键点击事件发生在哪,就可以在函数体内 获取 x,y = e.x_root, e.y_root(坐标相当于其master)
如果不用获取事件的某些属性,只是触发执行某个函数,那就可以写:self.widget.bind("<Button-3>", lambda e: self.xfunc(...) )





Wirror 发表于 2021-7-20 17:49:17

本帖最后由 Wirror 于 2021-7-20 18:32 编辑

阿奇_o 发表于 2021-7-20 16:07
先吐槽:这是谁教的代码,感觉乱得很,用了OOP还用global变量? 一个简单的GUI程序,搞两个类,有必要?

...

谢谢啊,我其实只是初学,今年刚上大学{:10_266:}
那两个类的代码是用一个软件生成的,他的说明是第一个类用于生成界面,第二个类继承后只写控件对应的函数,

还有,如果不用global的话,我要在控件的函数中关闭主窗口如何实现呢?
我这个文件中没有主函数


如果不用界面生成器的话我感觉tkinter用三个布局方法设置位置挺麻烦的,这个布局软件是用的vb的界面来生成窗口
这么说的话master是不是对应wx中的parent啊

要是我这样绑定的话为什么我没按回车也会调用ok函数啊

阿奇_o 发表于 2021-7-20 19:54:13

本帖最后由 阿奇_o 于 2021-7-20 20:15 编辑

Wirror 发表于 2021-7-20 17:49
谢谢啊,我其实只是初学,今年刚上大学
那两个类的代码是用一个软件生成的,他的说明是第一 ...

master, parent 的确是类似的意思。
就像 定义主窗口对象时,有的喜欢叫 root, 有的叫 win, window, 有的又叫 master

初学的话,可以先简单熟悉一下常用的组件,如 Label, Button, Entry,Toplevel, Canvas, Listbox 等等,
参考https://tkdocs.com/tutorial/index.html , https://realpython.com/python-gui-tkinter/
然后,直接做一个稍微复杂的,遇到问题 再Google搜具体的应用例子,如 tkinter open second window
靠前的通常是 stackoverflow.com, geeksforgeeks.com, realpython.com 等好网站

至于 tkinter的三个布局方法,一开始还是自己手工写实在,更能加强对GUI的理解。

我现在写的话,一般会这样:
from tkinter import *
from tkinter import ttk


class App(Tk):# 直接继承Tk类, 方便构造 主窗口对象
    def __init__(self, geo, title):
      super().__init__()
      self.geometry(geo)   # 理解:此时的 self 将是 主窗口对象,
      self.title(title)
      self.name = ''

      self.initUI()# 初始化UI
      # 初始化其他功能
      self.shortcut()

    def initUI(self):
      self.lb = Label(self, text='输入你的名字:')
      self.lb.pack(pady=10)
      self.ent = Entry(master=self, )
      self.ent.pack(pady=(10, 50))

      self.frame = Frame(master=self, width=250, height=50, background='white', )
      self.frame.pack(fill='y', expand=True)
      # self.frame.pack(fill='y', )# 注:pack布局方法,会影响frame的实际显示大小

      self.lb = Label(master=self.frame, text='Hello', font=('Helveta', 18))
      self.lb.grid(row=0, column=0, padx=10, pady=10)
      self.bt = Button(master=self.frame, text='click获取', command=self.get_name)
      self.bt.grid(row=0, column=1, padx=10, pady=10)

      self.bt_s = Button(self, text='打开新窗口', command=self.second_win)
      self.bt_s.pack()
   
    def shortcut(self):
      self.bind("<Control-q>", lambda e: self.destroy())# Ctrl+Q 关闭主窗口
      # self.ent.focus()
      self.ent.bind("<Return>", lambda e: self.get_name())# 当输入框激活时,按回车,触发函数
      # 绑定名称参考:https://anzeljg.github.io/rin2/book2/2405/docs/tkinter/key-names.html

    def get_name(self):
      self.lb['text'] = 'Hello, ' + self.ent.get()
      self.ent.delete(0, END)

    def second_win(self,):
      self.tl = Toplevel(self, bg='white')
      self.tl.geometry("1000x800")
      
      self.withdraw()# 隐藏主窗口
      # self.deiconify() # 显示主窗口
      

win = App(geo="500x300+200+100", title='tkinter GUI OOP Basic Demo') # 构造主窗口Tk对象
win.mainloop()

Twilight6 发表于 2021-7-21 07:59:01



添加事件中,self.ok 后去掉括号,另外 ok 加上 event 参数

页: [1]
查看完整版本: bind