daidingdaiding——python新手教程笔记(四)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_41185868/article/details/86586695

daidingdaiding——python新手教程笔记(四)


Lesson 13 写一个简单的界面很容易
图形界面是非常有吸引力的东西。但是制作出来似乎不是那么容易,这个观点对于用C来笨拙写windows的窗口程序来说,是比较正确的。微软公司出品的windows是一个图形界面的操作系统,这个和dos或者linux这些不一样,他们一开始出来是针对字符界面的,然后再在上面加上一些库来提供图形的功能。windows则不同,它是包含在自己的最原始的功能之中,而这些图形功能的提供是在user32.dll这样的system目录下的dll文件中以函数导出的形式提供的,但是要使用这些东西必须使用c语言的函数接口,而且编写麻烦。有一个很大的wndproc中要填入所有的事件处理代码,非常丑陋。而作为脚本语言,所应该有的简洁性,python对这个进行了封装。但是事情不是如你所想象。中间过程非常复杂,而且python用的也不是自己的库,还是tcl的一个tk的库再封装了一次。虽然经过层层封装,裹得非常严实,但是除了影响其在比较高性能的图形场合下的应用之外,并没有带来太大的麻烦。你能够用很少的代码,来完成其他语言+库要很大行代码才能表达的图形样式,虽然非常简陋,不过足够使用。而且python除了自己原包装带的这个tkinter库之外,还有其他的第三方的选择,比较丰富,而且也有能够胜任各种应用的选择。甚至,还有opengl和directx的库的封装库,能够用来编写2d和3d的游戏,这个非常的诱人哦。但是我不会,

图形界面的奥秘其实并不深奥。我相信很多人学习windows编程都是从写一个窗口开始的,而且都是从尝试理解那个消息和事件驱动的模型入手的。大体的过程是这样的,窗口就是用象素画出来的。你可以把一个窗口想象成一个窗口,也可以把窗口看成一堆象素的集合。就像有人说看女色不过是皮肉色相一样。而且窗口中的按钮,编辑矿,各种图标,无论是什么看起来像一个”物体“的东西,其实本质上都是有应用程序或者是库或者是操作系统调用显卡的驱动,通过显卡的功能在屏幕上绘画一些点出来。而所谓的”物体“有很多称法,在windows中一般成为控件(control)。

而对于图形界面的操控一般是通过鼠标和键盘来完成的。鼠标在屏幕上有一个自己的形象,那就是一个箭头(当然你也可以调整这个图形为其他好玩的东西,it is your freedom)。而键盘呢则一般表示为一个虚线的框,表示这个是键盘的”焦点“所在的地方。或者是编辑框中闪动的竖杠。这两点中有一个共同点,就是都有一个位置来确定要操作的对象。你点下鼠标的时候,你操作的就是鼠标的箭头尖端指向的那个空间,而键盘按下也是在其焦点所在的控件那儿放声。发生的是什么呢?发生的过程从硬件层面到软件层面之后,最终是被操作系统接收。操作系统能够知道你是点击的是鼠标还是键盘,在什么一个地方点下的,而且按下的是左键还是右键。操作系统还知道当前窗口各处摆放的位置。综合各路的信息,操作系统就能够知道把这个”事件“作为”消息“发送给哪个窗口来处理。从中应该能够明白什么叫事件,而消息呢则是一个C中的结构体,其中有几个field中间放了有关这个事件的信息,然后就像一封信一样从操作系统投递到了窗口所在的应用程序。然后应用程序有一个事先注册的”窗口过程“,其实就是一个函数,用来接收这封“信”。其实就是接收到传过来的参数。然后再进行一些判断,作出一定的响应。这个就是所谓的事件驱动。在没有冗长的代码,和展示所有细节的情况下,如果你真的以前对这个过程一无所知,肯定会觉得非常茫然。这个一笔带过的叙述其实只是让你有一个感性的认识。其实在python中使用窗口根本不用管诸葛么多。基本上只是把自己要的窗口和控件,给一些位置的参数,一些文字的提示内容的参数就能把窗口摆好,显示出来。然后再通过代码告诉python,当“这个按钮按下的时候执行这个函数”,然后就能让窗口有响应。最后记得给一个退出窗口的办法就一切OK了。其中能省的复杂度基本上都被库给隐藏掉了。付出的代价是慢一些,但是我就不相信你能感觉出来,除非你用的电脑连vcd都看不流畅。所以大可放心的享受这种便利。

OK,下面来正式的看看怎么在python中创建一个窗口,然后显示出来。

  代码:

from Tkinter import *
root = Tk()
root.mainloop()

 


就3行就能够把主窗口显示出来了。root是一个变量名称,其代表了这个主窗口。以后创建控件的时候指定控件创建在什么窗口之中,就要用这个root来表示了。而Tk()是一个Tkinter库之中的函数(其实是类的构造函数,构造了一个对象)。而mainloop则是主窗口的成员函数,也就是表示让这个root工作起来,开始接收鼠标的和键盘的操作。你现在就能够通过鼠标缩放以及关闭这个窗口了。注意到窗口的标题是tk,我们可以进行一些修改

root= Tk(className='bitunion')

然后窗口的标题就变成了bitunion了。下面要作的是把这个窗口的内容填充一下,让其有一些东西。先加入一个标签,所谓标签就是一行字。

  代码:

from Tkinter import *
root = Tk(className='bitunion')
label = Label(root)
label['text'] = 'be on your own'
label.pack()
root.mainloop()

 


我们很惊讶的发现窗口变小了,但是其中多了一行字。变小了是因为窗口中已经放了东西了,python的Tkinter非常智能,能够根据内容自动缩放,而不用和传统的windows程序一样,手工的指定绝对坐标了。对于label,它还是一个变量而已。不过这个变量代表了一个标签,也就是那一行字。而这个label的创建是用Label,而Label的参数是root表明了这个控件是root主窗口的成员控件,或者说是子窗口。label['text']表示设置这个标签的text属性为'be on your own',也就是文字内容了。label.pack和root.mainloop一样费解,但是内涵一样深刻。你现在可以简单理解为把label显示出来的功能,因为你把pack去掉,那你就看不到东西了。其实pack是和控件的布局排版有关西的。

再添加一个按钮就能够有更加丰富的内容了,方法是很类似的。看着吧:

  代码:

from Tkinter import *
root = Tk(className='bitunion')
label = Label(root)
label['text'] = 'be on your own'
label.pack()
button = Button(root)
button['text'] = 'change it'
button.pack()
root.mainloop()

 


只不过把button替换了label而Button替换了Label。注意一下Button和Label这些都是Tkinter这些库提供的,而button和Button这样大小写之间的差别仅仅是巧合,你能够随便的给变量取名字,但是Button和Label这些则是需要记住的东西,写代码的时候要经常用到的名字。但是点击按钮你会比较失望,因为并没有什么反应。不过也是当然的事情,你并没有告诉计算机对于这样一个按钮的点击操作需要作出一个什么样的反应来反馈给用户。而这个指定作出什么反应的工作只需要一个行,但是作出具体什么样反应的描述则需要新建一个函数来进行处理。

  代码:

from Tkinter import *
def on_click():
    label['text'] = 'no way out'
root = Tk(className='bitunion')
label = Label(root)
label['text'] = 'be on your own'
label.pack()
button = Button(root)
button['text'] = 'change it'
button['command'] = on_click
button.pack()
root.mainloop()

 


button['command'] = on_click表示对于button(按钮)的点击属性用on_click这个函数来处理。而on_click函数也很简洁,只是把label的文本重新设置一下。这个完成了一个事件消息的处理,如果用C来写,需要比这个长更加不好懂的写法。另外你是否会对on_click中出现label这个变量比较奇怪呢?明明在on_click前面没有定义label这个变量啊。如果我在C中这么写程序,编译器一定会告诉我出错的。而python是怎么知道label这个变量存在,然后没有报错的呢?其实python在你写的时候根本就不用知道其是否存在,只是要在运行的时候找得到label就可以了。而运行的前后关系,是通过时间来关联的而不是代码上前后行的关系。这里由于label = Label(root)先于on_click执行,所以当on_click执行的时候,label就是一个已经定义的变量。如果没有定义呢?那就报告出错喽。

最后一个例子:

  代码:

from Tkinter import *
def on_click():
    label['text'] = text.get()

root = Tk(className='bitunion')
label = Label(root)
label['text'] = 'be on your own'
label.pack()
text = StringVar()
text.set('change to what?')
entry = Entry(root)
entry['textvariable'] = text
entry.pack()
button = Button(root)
button['text'] = 'change it'
button['command'] = on_click
button.pack()
root.mainloop()

 


这个就比较复杂了。里面有一个StringVar。这个代表一个字符串,但是跟一般字符串不一样。一般的这样'dfsdf'的字符串是不可变的,你只能把变量指定为不同的字符串,但是字符串本身的内容是不可改变的。而StringVar则是可变的字符串。所以了set和get来设置和取得其内容。主要是entry(单行输入框)要求一个这样的属性来设置和接收其输入框的内容。一开始可能不习惯,但是用多了之后会觉得很方便的,因为只要用这个变量text,就能一直得到当前输入框的内容。当你能够完整的把这个例子看懂的时候,你已经入门了。

猜你喜欢

转载自blog.csdn.net/qq_41185868/article/details/86586695
今日推荐