概述
最近无所事事,前天老师让我写一个python爬虫软件,可以自定义调一些参数,用来下载一些视频。本来想着,爬虫啊,多么简单的事情… 然后就爽快的答应了… 然后就发生了一些匪夷所思的事情。特此说明一下。
如果有同学对视频爬虫感兴趣可以去B站看看本项目的研发心得:B站传送门:如何自制一款视频爬虫下载器
一.tkinter简介
tkinter作为python自带的UI库,不得不说,写一些(丑陋)的界面还是挺简单的,当然不是说人家就写不出好看的界面,大名鼎鼎的pyqt5还是可以的,相对而言,python写一款小工具还是蛮不错的,如果你试着用过java的swing编写,那将是多么令人乏味的一件事情呢?
二、tkinter的简答使用
如果你想使用tkinter创建一个窗口,非常简单,不罗嗦,看代码:
import tkinter
window = tkinter.Tk()
# 使主程序进入一个循环,用于监听其他事件(键盘、鼠标)
window.mainloop()
对的就是这么假单。有些同学说,不就一个窗口吗,没看出来有啥特点啊,你可能没用用过java的swing写过程序,虽然已经很过时了,但是其繁琐的布局设计,自定义布局每次都要setLayout(null)
,你就会明白原来把一件事情实现的过程越来越简单的感觉真好。
另外要注意的是,我们初始化控件的时候,一定要写在mainloop()
前面,因为mainloop
会使主线程陷入一个内部循环,无法执行后面的语句。
label控件的使用
import tkinter
window = tkinter.Tk()
select = tkinter.StringVar()
select.set("hello python")
label1 = tkinter.Label(window, text='hello world', font=('Arial', 12), bg='green', fg="white")
label1.place(x=40, y=100)
label2 = tkinter.Label(window, textvariable=select, font=('Arial', 12), bg='green', fg="white")
label2.place(x=40, y=200)
window.mainloop()
使用如上代码,我们就可以看到如下内容啦。
这些参数都很简单,就不一 一解释了。这里大家可能看到一个新的东西,也是带我走向钻牛角尖的地方。对了,就是textvariable
。这个东西其实也没什么,用起来也很简单,就相当于绑定一个变量到一个控件上,然后对这个变量set
可以改变这个控件的值,如上面的代码,select.set("hello python")
设置的值同步更新到窗口。
三、下拉框的简单使用
def gradesFunc():
print(gradesSelect.get())
if __name__ == '__main__':
window = tkinter.Tk()
grades = tkinter.Label(window, text='年级:', font=('Arial', 12))
grades.place(x=10, y=2)
gradesSelect = ttk.Combobox(window)
gradesSelect.pack()
gradesSelect['value'] = ['一年级', '二年级', '三年级']
gradesSelect.bind("<<ComboboxSelected>>", lambda event: gradesFunc())
window.mainloop()
ps:效果图
这个代码中,我们制作了一个简单的下拉框,同时为下拉框绑定了一个事件,当我们选中任意一条数据时,该事件将被触发。
四、列表框(listBox)
def listBoxMouseClick(event):
# 输出所有选中的下标值,类型为元祖
print(listBox.curselection())
if __name__ == '__main__':
# 设置窗口大小
width = 600
height = 600
window = tkinter.Tk()
# 获取屏幕尺寸以计算布局参数,使窗口居屏幕中央
screenwidth = window.winfo_screenwidth()
screenheight = window.winfo_screenheight()
alignstr = '%dx%d+%d+%d' % (width, height, (screenwidth - width ) /2, (screenheight - height ) /2)
window.geometry(alignstr)
listBox = tkinter.Listbox(window, selectmode=tkinter.MULTIPLE, width=80)
listBox.place(x=20, y=20)
listBox.insert(tkinter.END,'喜欢你没道理')
listBox.insert(tkinter.END, '不喜欢你更没道理')
listBox.bind('<<ListboxSelect>>', listBoxMouseClick)
window.mainloop()
效果如下图:
其中,我们给该列表框添加了点击事件,也就是说,每次点击数据条目时,都会触发一个事件,达到我们想要的目的,比如说:我们想做一个功能,用来获取 选中了几条数据呢?这样,添加个点击事件恰到好处。直接使用len(listBox.curselection())
即可。
这里,再简单说明下,其他可能用到的鼠标事件:
<Button-1> 鼠标左键
<Button-2> 鼠标中间键(滚轮)
<Button-3> 鼠标右键
<Double-Button-1> 双击鼠标左键
<Double-Button-3> 双击鼠标右键
<Triple-Button-1> 三击鼠标左键
<Triple-Button-3> 三击鼠标右键
要用到哪个直接绑定就好了.
以下介绍一些比较常用的api:
#用来选中所有行数
listBox.select_set(0, .size())
#取消选中所有行数
listBox.select_clear(0, size())
#获取第1行数据
listBox.get(0)
#将数据插入第二行
listBox.insert(1,'(●'◡'●)')
#数据从尾部插入
listBox.insert(Tkinter.END,'(●'◡'●)')
好了,本次就介绍这么几个控件。看看我被坑的地方在哪呢
面临的坑:
StringVar 何种情况会 失效?
import tkinter
def click():
select = tkinter.StringVar()
select.set("dd")
label = tkinter.Label(l, textvariable=select, font=('Arial', 12), bg='green', fg="white")
label.place(x=100, y=100)
window = tkinter.Tk()
window.title('new window')
# 为什么 label取不到数据
label2 = tkinter.Label(window, textvariable=select, font=('Arial', 12), bg='green', fg="white")
label2.place(x=100, y=100)
window.mainloop()
if __name__ == '__main__':
l = tkinter.Tk()
bt = tkinter.Button(l, text ="下载视频", font=('Arial', 15),command = click)
bt.place(x=50,y=50)
l.mainloop()
我编写项目的时候,遇到的问题,最后我抽象出来就是上面的形式,先创建一个窗口,按钮点击会再创建一个窗口,但是第二个窗口无法获取select = tkinter.StringVar()
变量设置的值,令我百思不得其解,我就是想知道为什么?但是我找遍了搜索引擎,没有找到,抱着对学习有着一种认真研究的精神,我钻牛角尖花费了一天多时间。
到最终,我终于 找到答案了,stackoverflow不愧是一个专业的地方。直接上图吧:
大致意思就是说,StringVar不能同时使用两个Tk(),只能同时可见于一个TK域中。献上链接:StringVar失效问题
另外: 提供一种他们所说的解决方案,也就是 不要创建两个TK窗口,创建一个即可,然后,再创建的窗口 通过Toplevel传入主窗口即可.如:newWindow = tk.Toplevel(window)
。注意:使用这种方案,生成的新窗口不必再使用mainloop了。
哇,终于解决了我的疑问。我一直觉得是玄学问题。
最后
以上就是和谐芒果为你收集整理的让人又爱又恨的tkinter之坑的全部内容,希望文章能够帮你解决让人又爱又恨的tkinter之坑所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复