鱼C论坛

 找回密码
 立即注册
查看: 1237|回复: 4

[已解决]bind

[复制链接]
发表于 2021-7-20 12:44:39 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
# 这段代码绑定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()
最佳答案
2021-7-21 07:59:01


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

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 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(...) )





想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-7-20 17:49:17 | 显示全部楼层
本帖最后由 Wirror 于 2021-7-20 18:32 编辑
阿奇_o 发表于 2021-7-20 16:07
先吐槽:这是谁教的代码,感觉乱得很,用了OOP还用global变量? 一个简单的GUI程序,搞两个类,有必要?

...


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

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


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

要是我这样绑定的话为什么我没按回车也会调用ok函数啊
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 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()
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-7-21 07:59:01 | 显示全部楼层    本楼为最佳答案   


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

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-1-14 01:07

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表