-
centos7安装图形化界面图文详解
2019-09-05 11:03:00centos7没有图形化操作可能对很多人来说都不太习惯,下面我们来为centos7安装图形化界面,本文以安装 GNOME 图形化为例 写在安装前: 如果你的centos7是最小化安装的那默认都是不带X WINDOWS的,那在安装图形化界面...欢迎关注微信公众号:【 全栈攻略 】
centos7没有图形化操作可能对很多人来说都不太习惯,下面我们来为centos7安装图形化界面,本文以安装 GNOME 图形化为例
写在安装前:
如果你的centos7是最小化安装的那默认都是不带X WINDOWS的,那在安装图形化界面之前,你得先安装一下X WINDOWS,这个控制功能yum groupinstall "X Window System"
1.输入安装命令
yum groupinstall -y "GNOME Desktop"
等待安装完成,出现Complete2.输入命令进入图形化界面
init 5
进入选择语言界面,我们当然选择汉语啦
3.选择地理位置服务开关
看个人需求,我这边默认开启4.选择时区
默认即可,当然你也可以自行更改5.连接在线帐号(可跳过)
对业务暂时没有什么用,我们跳过6.取一个用户名
7.设置密码
8.进入开始使用界面
9.点击开始使用,进入GNOME Help页面 , 点击右上角到 ❌,退出帮助页面
10.进入到登录页面,列出当前电脑到所有用户列表
11.点击对应用户,输入对应密码
12.第一次有点慢,等待片刻出现心仪到图形化操作界面了
至此,centos7安装图形化界面完美收官!PS:未来的你,一定会感谢今天拼命努力的自己!
-
Python-Tkinter图形化界面设计(详细教程 )
2019-08-05 23:07:41Python 图形化界面设计 文章参考:https://www.jianshu.com/p/91844c5bca78 1、图形化界面设计的基本理解 当前流行的计算机桌面应用程序大多数为图形化用户界面(Graphic User Interface,GUI),即通过鼠标对菜单...声明:本篇文章为转载自https://www.jianshu.com/p/91844c5bca78,在原作者的基础上添加目录导航,旨在帮助大家以更高效率进行学习和开发。
Python-Tkinter 图形化界面设计(详细教程)
本文目录
一.图形化界面设计的基本理解
当前流行的计算机桌面应用程序大多数为图形化用户界面(Graphic User Interface,GUI),即通过鼠标对菜单、按钮等图形化元素触发指令,并从标签、对话框等图型化显示容器中获取人机对话信息。
Python自带了tkinter 模块,实质上是一种流行的面向对象的GUI工具包 TK 的Python编程接口,提供了快速便利地创建GUI应用程序的方法。其图像化编程的基本步骤通常包括:○ 导入 tkinter 模块
○ 创建 GUI 根窗体
○ 添加人机交互控件并编写相应的函数。
○ 在主事件循环中等待用户触发事件响应。二.窗体控件布局
2.1. 数据集导入
根窗体是图像化应用程序的根控制器,是tkinter的底层控件的实例。当导入tkinter模块后,调用 Tk()方法可初始化一个根窗体实例 root ,用 title() 方法可设置其标题文字,用geometry()方法可以设置窗体的大小(以像素为单位)。将其置于主循环中,除非用户关闭,否则程序始终处于运行状态。执行该程序,一个窗体就呈现出来了。在这个主循环的根窗体中,可持续呈现中的其他可视化控件实例,监测事件的发生并执行相应的处理程序。下面是根窗体呈现示例:
from tkinter import * root= Tk() root.title('我的第一个Python窗体') root.geometry('240x240') # 这里的乘号不是 * ,而是小写英文字母 x root.mainloop()
2.2. tkinter 常用控件
返回目录
常用控件:常用的10 多种,如下:
2.2.1 控件的共同属性
返回目录
在窗体上呈现的可视化控件,通常包括尺寸、颜色、字体、相对位置、浮雕样式、图标样式和悬停光标形状等共同属性。不同的控件由于形状和功能不同,又有其特征属性。在初始化根窗体和根窗体主循环之间,可实例化窗体控件,并设置其属性。父容器可为根窗体或其他容器控件实例。常见的控件共同属性如下表:
标签及常见属性示例:from tkinter import * root = Tk() lb = Label(root,text='我是第一个标签',\ bg='#d3fbfb',\ fg='red',\ font=('华文新魏',32),\ width=20,\ height=2,\ relief=SUNKEN) lb.pack() root.mainloop()
其中,标签实例lb 在父容器root中实例化,具有代码中所示的text(文本)、bg(背景色)、fg(前景色)、font(字体)、width(宽,默认以字符为单位)、height(高,默认以字符为单位)和 relief(浮雕样式)等一系列属性。
在实例化控件时,实例的属性可以“属性=属性值”的形式枚举列出,不区分先后次序。例如:“ text=‘我是第一个标签’ ”显示标签的文本内容,“bg=’#d3fbfb’”设置背景色为十六进制数RGB色 #d3fbfb等等。属性值通常用文本形式表示。
当然如果这个控件实例只需要一次性呈现,也可以不必命名,直接实例化并布局呈现出来,例如:Label(root,text='我是第一个标签',font='华文新魏').pack()
属性 relief 为控件呈现出来的3D浮雕样式,有 FLAT(平的)、RAISED(凸起的)、SUNKEN(凹陷的)、GROOVE(沟槽状边缘)和 RIDGE(脊状边缘) 5种。
2.3 控件布局
返回目录
控件的布局通常有pack()、grid() 和 place() 三种方法。
pack和grid请参考:https://www.jianshu.com/p/91844c5bca782.3.1 place()方法
返回目录
根据控件实例在父容器中的绝对或相对位置参数进行布局。其常用布局参数如下:
x,y:控件实例在根窗体中水平和垂直方向上的其实位置(单位为像素)。注意,根窗体左上角为0,0,水平向右,垂直向下为正方向。
relx,rely:控件实例在根窗体中水平和垂直方向上起始布局的相对位置。即相对于根窗体宽和高的比例位置,取值在0.0~1.0之间。
height,width:控件实例本身的高度和宽度(单位为像素)。
relheight,relwidth:控件实例相对于根窗体的高度和宽度比例,取值在0.0~1.0之间。利用place()方法配合relx,rely和relheight,relwidth参数所得的到的界面可自适应根窗体尺寸的大小。place()方法与grid()方法可以混合使用。如下例子:利用place()方法排列消息(多行标签)。
from tkinter import * root = Tk() root.geometry('320x240') msg1 = Message(root,text='''我的水平起始位置相对窗体 0.2,垂直起始位置为绝对位置 80 像素,我的高度是窗体高度的0.4,宽度是200像素''',relief=GROOVE) msg1.place(relx=0.2,y=80,relheight=0.4,width=200) root.mainloop()
三、tkinter常见控件的特征属性
3.1、文本输入和输出相关控件
文本的输入与输出控件通常包括:标签(Label)、消息(Message)、输入框(Entry)、文本框(Text)。他们除了前述共同属性外,都具有一些特征属性和功能。
○ 3.1.1 标签(Label)和 消息(Message)
返回目录
除了单行与多行的不同外,属性和用法基本一致,用于呈现文本信息。值得注意的是:属性text通常用于实例在第一次呈现时的固定文本,而如果需要在程序执行后发生变化,则可以使用下列方法之一实现:1、用控件实例的configure()方法来改变属性text的值,可使显示的文本发生变化;2、先定义一个tkinter的内部类型变量var=StringVar() 的值也可以使显示文本发生变化。
看下面的一个例子:制作一个电子时钟,用root的after()方法每隔1秒time模块以获取系统当前时间,并在标签中显示出来。
方法一:利用configure()方法或config()来实现文本变化。
import tkinter import time def gettime(): timestr = time.strftime("%H:%M:%S") # 获取当前的时间并转化为字符串 lb.configure(text=timestr) # 重新设置标签文本 root.after(1000,gettime) # 每隔1s调用函数 gettime 自身获取时间 root = tkinter.Tk() root.title('时钟') lb = tkinter.Label(root,text='',fg='blue',font=("黑体",80)) lb.pack() gettime() root.mainloop()
方法二:利用textvariable变量属性来实现文本变化
import tkinter import time def gettime(): var.set(time.strftime("%H:%M:%S")) # 获取当前时间 root.after(1000,gettime) # 每隔1s调用函数 gettime 自身获取时间 root = tkinter.Tk() root.title('时钟') var=tkinter.StringVar() lb = tkinter.Label(root,textvariable=var,fg='blue',font=("黑体",80)) lb.pack() gettime() root.mainloop()
○ 3.1.2 文本框(Text)
文本框的常用方法如下:
上表位置的取值可为整数,浮点数或END(末尾),例如0.0表示第0列第0行
如下一个例子: 每隔1秒获取一次当前日期的时间,并写入文本框中,如下:本例中调用 datetime.now()获取当前日期时间,用insert()方法每次从文本框txt的尾部(END)开始追加文本。
from tkinter import * import time import datetime def gettime(): s=str(datetime.datetime.now())+'\n' txt.insert(END,s) root.after(1000,gettime) # 每隔1s调用函数 gettime 自身获取时间 root=Tk() root.geometry('320x240') txt=Text(root) txt.pack() gettime() root.mainloop()
○ 3.1.3 输入框(Entry)
返回目录
通常作为功能比较单一的接收单行文本输入的控件,虽然也有许多对其中文本进行操作的方法,但通常用的只有取值方法
get()
和用于删除文本的delete(起始位置,终止位置)
,例如:清空输入框为delete(0,END)
。3.2 按钮(Button)
返回目录
主要是为响应鼠标单击事件触发运行程序所设的,故其除控件共有属性外,属性
command
是最为重要的属性。通常,将按钮要触发执行的程序以函数形式预先定义,然后可以用一下两种方法调用函数。Button
按钮的状态有:'normal','active','disabled'
○ 直接调用函数。参数表达式为“
command=函数名”
,注意函数名后面不要加括号,也不能传递参数。如下面的command=run1:
○ 利用匿名函数调用函数和传递参数。参数的表达式为“command=lambda”:函数名(参数列表)
。例如下面的:"command=lambda:run2(inp1.get(),inp2.get())
"。○ 看下面的例子:1.从两个输入框去的输入文本后转为浮点数值进行加法运算,要求每次单击按钮产生的算是结果以文本的形式追加到文本框中,将原输入框清空。2.按钮方法一不传参数调用函数run1()实现,按钮“方法二”用lambda调用函数run2(x,y)同时传递参数实现。
from tkinter import * def run1(): a = float(inp1.get()) b = float(inp2.get()) s = '%0.2f+%0.2f=%0.2f\n' % (a, b, a + b) txt.insert(END, s) # 追加显示运算结果 inp1.delete(0, END) # 清空输入 inp2.delete(0, END) # 清空输入 def run2(x, y): a = float(x) b = float(y) s = '%0.2f+%0.2f=%0.2f\n' % (a, b, a + b) txt.insert(END, s) # 追加显示运算结果 inp1.delete(0, END) # 清空输入 inp2.delete(0, END) # 清空输入 root = Tk() root.geometry('460x240') root.title('简单加法器') lb1 = Label(root, text='请输入两个数,按下面两个按钮之一进行加法计算') lb1.place(relx=0.1, rely=0.1, relwidth=0.8, relheight=0.1) inp1 = Entry(root) inp1.place(relx=0.1, rely=0.2, relwidth=0.3, relheight=0.1) inp2 = Entry(root) inp2.place(relx=0.6, rely=0.2, relwidth=0.3, relheight=0.1) # 方法-直接调用 run1() btn1 = Button(root, text='方法一', command=run1) btn1.place(relx=0.1, rely=0.4, relwidth=0.3, relheight=0.1) # 方法二利用 lambda 传参数调用run2() btn2 = Button(root, text='方法二', command=lambda: run2(inp1.get(), inp2.get())) btn2.place(relx=0.6, rely=0.4, relwidth=0.3, relheight=0.1) # 在窗体垂直自上而下位置60%处起,布局相对窗体高度40%高的文本框 txt = Text(root) txt.place(rely=0.6, relheight=0.4) root.mainloop()
3.3 单选按钮
返回目录
(Radiobutton)是为了响应故乡排斥的若干单选项的单击事件以触发运行自定义函数所设的,该控件排除具有共有属性外,还具有显示文本(text)、返回变量(variable)、返回值(value)、响应函数名(command)等重要属性。响应函数名“command=函数名”的用法与Button相同,函数名最后也要加括号。返回变量variable=var通常应预先声明变量的类型var=IntVar()或var=StringVar(),在所调用的函数中方可用var.get()方法获取被选中实例的value值。例如下面:
from tkinter import * def Mysel(): dic = {0:'甲',1:'乙',2:'丙'} s = "您选了" + dic.get(var.get()) + "项" lb.config(text = s) root = Tk() root.title('单选按钮') lb = Label(root) lb.pack() var = IntVar() rd1 = Radiobutton(root,text="甲",variable=var,value=0,command=Mysel) rd1.pack() rd2 = Radiobutton(root,text="乙",variable=var,value=1,command=Mysel) rd2.pack() rd3 = Radiobutton(root,text="丙",variable=var,value=2,command=Mysel) rd3.pack() root.mainloop()
3.4 复选框
返回目录
(Checkbutton) 是为了返回多个选项值的交互控件,通常不直接触发函数的执行。该控件除具有共有属性外,还具有显示文本(text)、返回变量(variable)、选中返回值(onvalue)和未选中默认返回值(offvalue)等重要属性。返回变量variable=var 通常可以预先逐项分别声明变量的类型var=IntVar() (默认)或 var=StringVar(), 在所调用的函数中方可分别调用 var.get()方法 取得被选中实例的 onvalue或offvalue值。复选框实例通常还可分别利用 select()、deselect()和 toggle() 方法对其进行选中、清除选中和反选操作。
○ 如下的例子: 利用复选框实现,单击OK,可以将选中的结果显示在标签上。效果如下:
○ 方法:利用函数中的 if-else 分支实现多项显示from tkinter import * import tkinter def run(): if(CheckVar1.get()==0 and CheckVar2.get()==0 and CheckVar3.get()==0 and CheckVar4.get()==0): s = '您还没选择任何爱好项目' else: s1 = "足球" if CheckVar1.get()==1 else "" s2 = "篮球" if CheckVar2.get() == 1 else "" s3 = "游泳" if CheckVar3.get() == 1 else "" s4 = "田径" if CheckVar4.get() == 1 else "" s = "您选择了%s %s %s %s" % (s1,s2,s3,s4) lb2.config(text=s) root = tkinter.Tk() root.title('复选框') lb1=Label(root,text='请选择您的爱好项目') lb1.pack() CheckVar1 = IntVar() CheckVar2 = IntVar() CheckVar3 = IntVar() CheckVar4 = IntVar() ch1 = Checkbutton(root,text='足球',variable = CheckVar1,onvalue=1,offvalue=0) ch2 = Checkbutton(root,text='篮球',variable = CheckVar2,onvalue=1,offvalue=0) ch3 = Checkbutton(root,text='游泳',variable = CheckVar3,onvalue=1,offvalue=0) ch4 = Checkbutton(root,text='田径',variable = CheckVar4,onvalue=1,offvalue=0) ch1.pack() ch2.pack() ch3.pack() ch4.pack() btn = Button(root,text="OK",command=run) btn.pack() lb2 = Label(root,text='') lb2.pack() root.mainloop()
3.5 列表框 与 组合框
3.5.1 列表框
返回目录
(Listbox) 可供用户单选或多选所列条目以形成人机交互。列表框控件的主要方法见下面的表:
执行自定义函数时,通常使用“实例名.surselection()” 或 “selected” 来获取选中项的位置索引。由于列表框实质上就是将Python 的列表类型数据可视化呈现,在程序实现时,也可直接对相关列表数据进行操作,然后再通过列表框展示出来,而不必拘泥于可视化控件的方法。看下面的一个例子:实现列表框的初始化、添加、插入、修改、删除和清空操作,如下:
from tkinter import * def ini(): Lstbox1.delete(0,END) list_items = ["数学","物理","化学","语文","外语"] for item in list_items: Lstbox1.insert(END,item) def clear(): Lstbox1.delete(0,END) def ins(): if entry.get() != '': if Lstbox1.curselection() == (): Lstbox1.insert(Lstbox1.size(),entry.get()) else: Lstbox1.insert(Lstbox1.curselection(),entry.get()) def updt(): if entry.get() != '' and Lstbox1.curselection() != (): selected=Lstbox1.curselection()[0] Lstbox1.delete(selected) Lstbox1.insert(selected,entry.get()) def delt(): if Lstbox1.curselection() != (): Lstbox1.delete(Lstbox1.curselection()) root = Tk() root.title('列表框实验') root.geometry('320x240') frame1 = Frame(root,relief=RAISED) frame1.place(relx=0.0) frame2 = Frame(root,relief=GROOVE) frame2.place(relx=0.5) Lstbox1 = Listbox(frame1) Lstbox1.pack() entry = Entry(frame2) entry.pack() btn1 = Button(frame2,text='初始化',command=ini) btn1.pack(fill=X) btn2 = Button(frame2,text='添加',command=ins) btn2.pack(fill=X) btn3 = Button(frame2,text='插入',command=ins) # 添加和插入功能实质上是一样的 btn3.pack(fill=X) btn4 = Button(frame2,text='修改',command=updt) btn4.pack(fill=X) btn5 = Button(frame2,text='删除',command=delt) btn5.pack(fill=X) btn6 = Button(frame2,text='清空',command=clear) btn6.pack(fill=X) root.mainloop()
3.5.2 组合框
返回目录
(Combobox) 实质上是带文本框的上拉列表框,其功能也将是Python 的列表类型数据可视化呈现,并提供用户单选或多选所列条目以形成人机交互。在图形化界面设计时,由于其具有灵活的界面,因此往往比列表框更受喜爱。但该控件并不包含在 tkinter 模块中,而是与 TreeView、Progressbar、Separator等控件一同包含在tkinter 的子模块ttk中。如果使用该控件,应先与from tkinter import ttk 语句引用ttk子模块,然后创建组合框实例: 实例名=Combobox(根对象,[属性列表])
指定变量var=StringVar(),并设置实例属性 textvariable = var,values=[列表…]。组合框控件常用方法有:获得所选中的选项值get()和获得所选中的选项索引current()。
看下面的一个例子:实现四则运算计算器,将两个操作数分别填入两个文本框后,通过选择组合框中的算法触发运算,如下:
from tkinter.ttk import * def calc(event): a = float(t1.get()) b = float(t2.get()) dic = {0:a+b,1:a-b,2:a*b,3:a/b} c = dic[comb.current()] lbl.config(text=str(c)) root = Tk() root.title('四则运算') root.geometry('320x240') t1 = Entry(root) t1.place(relx=0.1,rely=0.1,relwidth=0.2,relheight=0.1) t2 = Entry(root) t2.place(relx=0.5,rely=0.1,relwidth=0.2,relheight=0.1) var = StringVar() comb = Combobox(root,textvariable=var,values=['加','减','乘','除',]) comb.place(relx=0.1,rely=0.5,relwidth=0.2) comb.bind('<<ComboboxSelected>>',calc) lbl=Label(root,text='结果') lbl.place(relx=0.5,rely=0.7,relwidth=0.2,relheight=0.3) root.mainloop()
3.6 滑块
返回目录
(Scale) 是一种 直观地进行数值输入的交互控件,其主要属性见下表:
滑块控件实例的主要方法比较简单,有get()
和set
(值),分别为取值和将滑块设在某特定值上。滑块实例也可绑定鼠标左键释放事件<ButtoonRelease-1>
,并在执行函数中添加参数event来实现事件响应。
例如:在一个窗体上设计一个200
像素宽的水平滑块,取值范围为1.0~5.0
,分辨精度为0.05
,刻度间隔为1
,用鼠标拖动滑块后释放鼠标可读取滑块值并显示在标签上。效果如下:
from tkinter import * def show(event): s = '滑块的取值为' + str(var.get()) lb.config(text=s) root = Tk() root.title('滑块实验') root.geometry('320x180') var=DoubleVar() scl = Scale(root,orient=HORIZONTAL,length=200,from_=1.0,to=5.0,label='请拖动滑块',tickinterval=1,resolution=0.05,variable=var) scl.bind('<ButtonRelease-1>',show) scl.pack() lb = Label(root,text='') lb.pack() root.mainloop()
3.7 菜单
返回目录
(Menu)用于可视化地为一系列的命令分组,从而方便用户找到和触发执行这些命令。这里Menu所实例化别的主要是菜单,其通式为:
菜单实例名=Menu(根窗体) 菜单分组1=Menu(菜单实例名) 菜单实例名.add_cascade(<label=菜单分组1 显示文本>,<menu=菜单分组1>) 菜单分组1.add_command(<label=命令1文本>,<command=命令1函数名>)
其中较为常见的方法有:
add_cascade()
、add_command()
和add_separator()
,分别用于添加一个菜单分组、添加一条菜单命令和添加一条分割线。
利用Menu控件也可以创建快捷菜单(又称为上下文菜单)。通常需要右击弹出的控件实例绑定鼠标右击响应事件,并指向一个捕获event参数的自定义函数,在该自定义函数中,将鼠标的触发位置event.x_root 和 event.y_root以post()方法传给菜单。
例子: 仿照window自带的“记事本”中的文件和编辑 菜单,实现在主菜单个快捷菜单上触发菜单命令,并相应改变窗体上的标签的文本内容。效果如下:
from tkinter import * def new(): s = '新建' lb1.config(text=s) def ope(): s = '打开' lb1.config(text=s) def sav(): s = '保存' lb1.config(text=s) def cut(): s = '剪切' lb1.config(text=s) def cop(): s = '复制' lb1.config(text=s) def pas(): s = '粘贴' lb1.config(text=s) def popupmenu(event): mainmenu.post(event.x_root,event.y_root) root = Tk() root.title('菜单实验') root.geometry('320x240') lb1 = Label(root,text='显示信息',font=('黑体',32,'bold')) lb1.place(relx=0.2,rely=0.2) mainmenu = Menu(root) menuFile = Menu(mainmenu) # 菜单分组 menuFile mainmenu.add_cascade(label="文件",menu=menuFile) menuFile.add_command(label="新建",command=new) menuFile.add_command(label="打开",command=ope) menuFile.add_command(label="保存",command=sav) menuFile.add_separator() # 分割线 menuFile.add_command(label="退出",command=root.destroy) menuEdit = Menu(mainmenu) # 菜单分组 menuEdit mainmenu.add_cascade(label="编辑",menu=menuEdit) menuEdit.add_command(label="剪切",command=cut) menuEdit.add_command(label="复制",command=cop()) menuEdit.add_command(label="粘贴",command=pas()) root.config(menu=mainmenu) root.bind('Button-3',popupmenu) # 根窗体绑定鼠标右击响应事件 root.mainloop()
3.8 子窗体
返回目录
用Toplevel可新建一个显示在最前面的子窗体,其通式为: 字体实例名=Toplevel(根窗体),子窗体与根窗体类似,也可设置title、geomerty等属性,并在画布上布局其他控件。如下的例子:在根窗体上创建菜单,触发创建一个新的窗体
from tkinter import * def newwind(): winNew = Toplevel(root) winNew.geometry('320x240') winNew.title('新窗体') lb2 = Label(winNew,text='我在新窗体上') lb2.place(relx=0.2,rely=0.2) btClose=Button(winNew,text='关闭',command=winNew.destroy) btClose.place(relx=0.7,rely=0.5) root = Tk() root.title('新建窗体实验') root.geometry('320x240') lb1 = Label(root,text='主窗体',font=('黑体',32,'bold')) lb1.place(relx=0.2,rely=0.2) mainmenu = Menu(root) menuFile = Menu(mainmenu) mainmenu.add_cascade(label='菜单',menu=menuFile) menuFile.add_command(label='新窗体',command=newwind) menuFile.add_separator() menuFile.add_command(label='退出',command=root.destroy) root.config(menu=mainmenu) root.mainloop()
关闭窗体程序运行的方法通常用 destory(),而不建议用 quit()。用Toplevel 所创建的子窗体是非模式(Modeless)的窗体,虽然初建时子窗体在最前面,但根窗体上的控件实例也是可以被操作的。
3.9 模式对话框(Modal)
返回目录
是相对于前面介绍的非模式窗体而言的,所弹出的对话框必须应答,在关闭之前无法操作其后面的其他窗体。常见的模式对话框有消息对话框、输入对话框、文件选择对话框、颜色选择对话框等。
3.9.1 交互对话框
返回目录
(一)、消息对话框: 引用 tkinter.messagebox 包,可使用消息对话框函数。执行这些函数,可弹出模式消息对话框,并根据用户的响应但会一个布尔值。其通式为:
消息对话框函数(<title=标题文本>,<message=消息文本>,[其他参数])
看下面的例子:单击按钮,弹出确认取消对话框,并将用户回答显示在标签中。效果如下:
from tkinter import * import tkinter.messagebox def xz(): answer=tkinter.messagebox.askokcancel('请选择','请选择确定或取消') if answer: lb.config(text='已确认') else: lb.config(text='已取消') root = Tk() lb = Label(root,text='') lb.pack() btn=Button(root,text='弹出对话框',command=xz) btn.pack() root.mainloop()
(二)、输入对话框: 引用tkinter.simpledialog包,可弹出输入对话框,用以接收用户的简单输入。输入对话框常用 askstring()、askfloat()和askfloat() 三种函数,分别用于接收字符串、整数和浮点数类型的输入。
如下面的例子:单击按钮,弹出输入对话框,接收文本输入显示在窗体的标签上。如下:
from tkinter.simpledialog import * def xz(): s=askstring('请输入','请输入一串文字') lb.config(text=s) root = Tk() lb = Label(root,text='') lb.pack() btn=Button(root,text='弹出输入对话框',command=xz) btn.pack() root.mainloop()
3.9.2 文件选择对话框
返回目录
引用tkinter.filedialog包,可弹出文件选择对话框,让用户直观地选择一个或一组文件,以供进一步的文件操作。常用的文件选择对话框函数有 askopenfilename()、askopenfilenames()和asksaveasfilename(),分别用于进一步打开一个文件、一组文件和保存文件。其中,askopenfilename()和asksaveasfilenamme()函数的返回值类型为包含文件路径的文件名字符串,而askopenfilenames()函数的返回值类型为元组。
例如:单击按钮,弹出文件选择对话框(“打开”对话框),并将用户所选择的文件路径和文件名显示在窗体的标签上。如下
from tkinter import * import tkinter.filedialog def xz(): filename=tkinter.filedialog.askopenfilename() if filename != '': lb.config(text='您选择的文件是'+filename) else: lb.config(text='您没有选择任何文件') root = Tk() lb = Label(root,text='') lb.pack() btn=Button(root,text='弹出文件选择对话框',command=xz) btn.pack() root.mainloop()
3.9.3、颜色选择对话框
返回目录
引用tkinter.colorchooser包,可使用 askcolor()函数弹出模式颜色选择对话框,让用户可以个性化地设置颜色属性。该函数的返回形式为包含RGB十进制浮点元组和RGB十六进制字符串的元组类型,例如:“((135.527343.52734375,167.65234375,186.7265625)),’#87a7ba’”。通常,可将其转换为字符串类型后,再截取以十六进制数表示的RGB颜色字符串用于为属性赋值。
举例:单击按钮,弹出颜色选择对话框,并将用户所选择的颜色设置为窗体上标签的背景颜色,如下:
from tkinter import * import tkinter.colorchooser def xz(): color=tkinter.colorchooser.askcolor() colorstr=str(color) print('打印字符串%s 切掉后=%s' % (colorstr,colorstr[-9:-2])) lb.config(text=colorstr[-9:-2],background=colorstr[-9:-2]) root = Tk() lb = Label(root,text='请关注颜色的变化') lb.pack() btn=Button(root,text='弹出颜色选择对话框',command=xz) btn.pack() root.mainloop()
四、事件响应
返回目录
用tkinter 可将用户事件与自定义函数绑定,用键盘或鼠标的动作事件来响应触发自定义函数的执行。其通式为:
控件实例.bind(<事件代码>,<函数名>)
其中,事件代码通常以半角小于号“<”和大于号“>” 界定,包括事件和按键等 2~3个部分,它们之间用减号分隔,常见事件代码见下表:
例如,将框架控件实例frame 绑定鼠标右键单击事件,调用自定义函数 myfunc()可表示为"frame.bind(’’,myfunc)",注意: myfunc后面没有括号。将控件实例绑定到键盘事件和部分光标不落在具体控件实例上的鼠标事件时,还需要设置该实例执行focus_set() 方法获得焦点,才能对事件持续响应。例如: frame.focus_set()。所调用的自定义函数若需要利用鼠标或键盘的响应值,可将event作为参数,通过event的属性获取。event的属性见下表:
from tkinter import * def show(event): s=event.keysym lb.config(text=s) root=Tk() root.title('按键实验') root.geometry('200x200') lb=Label(root,text='请按键',font=('黑体',48)) lb.bind('<Key>',show) lb.focus_set() lb.pack() root.mainloop()
补充:
五、背景图片
1、添加背景
返回目录
#插入文件图片 import tkinter as tk root = tk.Tk() #创建一个标签类, [justify]:对齐方式 textLabel = tk.Label(root,text="你在右边会看到一个图片,\n我在换个行", justify = tk.LEFT)#左对齐 textLabel.pack(side=tk.LEFT)#自动对齐,side:方位 #创建一个图片管理类 photo = tk.PhotoImage(file="18.png")#file:t图片路径 imgLabel = tk.Label(root,image=photo)#把图片整合到标签类中 imgLabel.pack(side=tk.RIGHT)#自动对齐 tk.mainloop()
返回目录
import tkinter as tk root = tk.Tk() #增加背景图片 photo = tk.PhotoImage(file="背景.png") theLabel = tk.Label(root, text="我是内容,\n请你阅读",#内容 justify=tk.LEFT,#对齐方式 image=photo,#加入图片 compound = tk.CENTER,#关键:设置为背景图片 font=("华文行楷",20),#字体和字号 fg = "white")#前景色 theLabel.pack() tk.mainloop()
返回目录
#插入文件图片 import tkinter as tk root = tk.Tk() frame1 = tk.Frame(root)#这是上面的框架 frame2 = tk.Frame(root)#这是下面的框架 var = tk.StringVar()#储存文字的类 var.set("你在右边会看到一个图片,\n我在换个行")#设置文字 #创建一个标签类, [justify]:对齐方式,[frame]所属框架 textLabel = tk.Label(frame1,textvariable=var, justify = tk.LEFT)#显示文字内容 textLabel.pack(side=tk.LEFT)#自动对齐,side:方位 #创建一个图片管理类 photo = tk.PhotoImage(file="18.png")#file:t图片路径 imgLabel = tk.Label(frame1,image=photo)#把图片整合到标签类中 imgLabel.pack(side=tk.RIGHT)#自动对齐 def callback():#触发的函数 var.set("你还真按了")#设置文字 #[frame]所属框架 ,text 文字内容 command:触发方法 theButton = tk.Button(frame2,text="我是下面的按钮",command=callback) theButton.pack()#自动对齐 frame1.pack(padx=10,pady=10)#上框架对齐 frame2.pack(padx=10,pady=10)#下框架对齐 tk.mainloop()
返回目录
六、打开摄像头,显示
效果:
代码:from tkinter import * import cv2 from PIL import Image,ImageTk def take_snapshot(): print("有人给你点赞啦!") def video_loop(): success, img = camera.read() # 从摄像头读取照片 if success: cv2.waitKey(100) cv2image = cv2.cvtColor(img, cv2.COLOR_BGR2RGBA)#转换颜色从BGR到RGBA current_image = Image.fromarray(cv2image)#将图像转换成Image对象 imgtk = ImageTk.PhotoImage(image=current_image) panel.imgtk1 = imgtk panel.config(image=imgtk) root.after(1, video_loop) camera = cv2.VideoCapture(0) #摄像头 root = Tk() root.title("opencv + tkinter") #root.protocol('WM_DELETE_WINDOW', detector) panel = Label(root) # initialize image panel panel.pack(padx=10, pady=10) # root.config(cursor="arrow") btn = Button(root, text="点赞!", command=take_snapshot) btn.pack(fill="both", expand=True, padx=10, pady=10) video_loop() root.mainloop() # 当一切都完成后,关闭摄像头并释放所占资源 camera.release() cv2.destroyAllWindows()
感谢前辈:
https://www.jianshu.com/p/91844c5bca78
https://www.cnblogs.com/banzhen/p/7427201.html
https://blog.csdn.net/a1_a1_a/article/details/79981788 -
【kimol君的无聊小发明】—用python写论文下载器(图形化界面)
2021-01-22 19:59:39【kimol君的无聊小发明】—用python写论文下载器(图形化界面)前言一、使用说明二、代码分析1. 功能函数2. 回调函数3. 线程生成函数4. 效果展示写在最后 前言 某个夜深人静的夜晚,夜微凉风微扬,月光照进我的书房...前言
某个夜深人静的夜晚,夜微凉风微扬,月光照进我的书房~
当我打开文件夹以回顾往事之余,惊现许多看似杂乱的无聊代码。我拍腿正坐,一个想法油然而生:“生活已然很无聊,不如再无聊些叭”。
于是,我决定开一个专题,便称之为kimol君的无聊小发明。
妙…啊~~~
在科研学习的过程中,我们难免需要查询相关的文献资料,而想必很多小伙伴都知道SCI-HUB,此乃一大神器,它可以帮助我们搜索相关论文并下载其原文。可以说,SCI-HUB造福了众多科研人员,用起来也是“美滋滋”。
在上一篇文章中介绍了分析过程以及相应的函数代码。根据小伙伴们的反映发现了一些问题,毕竟命令框的形式用起来难免没那么“丝滑”。为了让大家更方便地使用,可以“纵享丝滑”,kimol君决定写一个图形界面(GUI):
(PS.由于近期实属忙到晕厥,这是kimol君用疯狂压榨出来的时间写的,所以界面比较简陋,还望大家多多体谅哦~)一、使用说明
这个小玩意儿我们姑且称之为“SCI-Downloader”好了~
它支持单篇论文下载和批量论文下载:- 单篇下载:在论文标题栏输入论文的标题、DOI号或PMID号,然后选择论文存储的目录,点击开始即可!
- 批量下载:在论文标题那里选择一个.txt文本,文本里面包含了每篇需要下载的论文,其格式如下:
然后,emmm…没有然后了~
就是这么简单快捷,还不快来试试看,等啥呢?
二、代码分析
本次图形界面的开发是基于PyQT5的,具体界面的布置这里就不过多的介绍了,主要是对其中的功能实现进行说明:
其实思路很简单,由于之前已经有了论文下载的相关函数,我们只需要定义一个Button,然后将其绑定到下载函数即可。
这有啥?完全没难度嘛。然而,你试过就会知道,界面卡顿了。这是因为下载函数所消耗的时间较长,如果让它直接在主线程里面执行的话,将会和维持界面的主程序冲突,从而出现卡顿。因此,我们将要用到QThread来执行功能函数,回调函数来进行界面更新,示意图如下:
当然,这个示意图并不是那么严谨,大家辩证地看看就好了。这么一来,每个功能即可分为三个部分:Qthread类的功能函数、回调函数、线程生成函数(该函数与Button直接绑定)。1. 功能函数
继承Qthread类,并对其中的run函数进行重定义,这是实现具体功能的模块,并且把状态通过signal的方式传递给回调函数:
class runthread(QtCore.QThread): # 通过类成员对象定义信号对象 _signal = QtCore.pyqtSignal(str) def __init__(self, titleText, saveText): super(runthread, self).__init__() self.titleText = titleText self.saveText = saveText def __del__(self): self.wait() def run(self): if self.titleText == '' or self.saveText == '': # 如果为空 self._signal.emit('EMPTY') return headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.3; Win64; x64; rv:84.0) Gecko/20100101 Firefox/84.0', 'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', 'Accept-Language':'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2', 'Accept-Encoding':'gzip, deflate, br', 'Connection':'keep-alive', 'Upgrade-Insecure-Requests':'1'} if not self.titleText.endswith('.txt'): # 如果不为目录(即单篇论文标题) self._signal.emit('SEARCH') downUrl = search_article(self.titleText) if downUrl == '': # 如果搜索结果为空 self._signal.emit('NULL') return else: try: self._signal.emit('DOWNLOAD') res = requests.get(downUrl, headers=headers, stream=True) fileSize = int(res.headers['Content-Length']) print(fileSize) savedSize = 0 saveName = change_title(self.titleText) with open('%s/%s.pdf'%(self.saveText,saveName), 'wb') as f: for chunk in res.iter_content(chunk_size=1024): if chunk: f.write(chunk) savedSize += len(chunk) progress = int(savedSize/fileSize*100) self._signal.emit('PRO-%d'%progress) self._signal.emit('SUCCESS') except: self._signal.emit('FAILED') else: paperList = read_file(self.titleText) if paperList == '': self._signal.emit('FILEWRONG') else: error = [] # 用于记录失败的论文 self._signal.emit('BATCH-%d'%len(paperList)) for i in range(len(paperList)): try: downUrl = search_article(paperList[i]) print(downUrl) pdf = download_article(downUrl) saveName = change_title(paperList[i]) with open('%s/%s.pdf'%(self.saveText,saveName), 'wb') as f: f.write(pdf) except: error.append(paperList[i]) self._signal.emit('NUM-%d'%(i+1)) with open('./errors.txt', 'w') as f: for e in error: f.write(e+'\n') self._signal.emit('COMPLETED-%d'%len(error))
2. 回调函数
通过监听来自功能函数的信号,对界面进行相应的更新,例如错误提醒或者下载完毕提示等等:
def call_backrun(self, msg): if msg == 'EMPTY': QtWidgets.QMessageBox.warning(self.centralwidget, '警告', '标题或目录为空!') if msg == 'SEARCH': self.runButton.setVisible(False) self.quitButton.setVisible(False) self.searchLabel.setVisible(True) if msg == 'NULL': self.runButton.setVisible(True) self.quitButton.setVisible(True) self.searchLabel.setVisible(False) QtWidgets.QMessageBox.information(self.centralwidget, '提示', '未搜到相应论文!') if msg == 'DOWNLOAD': self.searchLabel.setVisible(False) self.progressBar.setVisible(True) self.progressBar.setFormat('%%p') self.progressBar.setValue(0) if 'PRO' in msg: pro = int(msg.split('-')[-1]) self.progressBar.setValue(pro) if msg == 'SUCCESS': self.progressBar.setVisible(False) self.runButton.setVisible(True) self.quitButton.setVisible(True) self.titleEdit.setText('') QtWidgets.QMessageBox.information(self.centralwidget, '提示', '论文下载完毕!') if msg == 'FAILED': self.progressBar.setVisible(False) self.runButton.setVisible(True) self.quitButton.setVisible(True) QtWidgets.QMessageBox.information(self.centralwidget, '提示', '论文下载失败!') if msg == 'FILEWRONG': QtWidgets.QMessageBox.information(self.centralwidget, '提示', '论文列表错误!') if 'BATCH' in msg: sumNumber = msg.split('-')[-1] self.runButton.setVisible(False) self.quitButton.setVisible(False) self.progressBar.setVisible(True) self.progressBar.setFormat('【%v/'+sumNumber+'】') self.progressBar.setMinimum(0) self.progressBar.setMaximum(int(sumNumber)) self.progressBar.setValue(0) if 'NUM' in msg: num = int(msg.split('-')[-1]) self.progressBar.setValue(num) if 'COMPLETED' in msg: errorNum = int(msg.split('-')[-1]) self.progressBar.setVisible(False) self.runButton.setVisible(True) self.quitButton.setVisible(True) self.titleEdit.setText('') QtWidgets.QMessageBox.information(self.centralwidget, '提示', '论文下载完毕!\n(%d个失败)'%errorNum)
3. 线程生成函数
这个函数与相应的按钮(Button)绑定,当触发时即创建一个对应的功能函数线程:
def run(self): titleText = self.titleEdit.text() saveText = self.saveEdit.text() # 创建线程 self.runthread = runthread(titleText, saveText) # 连接信号 self.runthread._signal.connect(self.call_backrun) # 进程连接回传到GUI的事件 # 开始线程 self.runthread.start()
4. 效果展示
大功告成之后,点击开始按钮,一键入魂:
无数的论文正在快马加鞭地向我奔来~写在最后
通过简单地测试,功能基本上没有太大的问题,就是界面可能相对比较简陋,后续如果有时间的话我也将持续更新,当然也欢迎各位大大提出宝贵的意见呀~
此外,为了让大家更方便地使用,我已经将代码打包exe可执行文件,双击即可开启新世界的大门,不爽吗?
如果需要完整代码以及SCI下载器可以关注下方公众号,后台回复“论文下载”即可获取,kimol君期待着您的光临~
我是kimol君,咋们下次再会~
创作不易,大侠请留步… 动起可爱的双手,来个赞再走呗 (๑◕ܫ←๑)
-
Centos进入图形化界面和退出图形化界面
2019-12-10 16:12:43在安装好图形化界面的命令行输入:startx 从图形化界面退出到命令行界面: 点击右上角用户名:选择Quit... 然后再点击:Log Out就会退出图形化界面 ...在安装好图形化界面的命令行输入:startx
从图形化界面退出到命令行界面:
点击右上角用户名:选择Quit... 然后再点击:Log Out就会退出图形化界面
-
CentOS7没有图形化界面,怎么安装图形化界面
2020-09-27 11:49:37我们在安装CentOS7时,如果选择 “最小化” 安装那么系统就只有命令行界面,但是没有图形化界面,如下图: 解决的完整步骤如下: 1)开启CentOS7并登录root用户(一定要以root用户登录,其他普通用户的权限不够),... -
Ubuntu 16.04纯文本界面、图形化界面切换方法
2018-02-08 14:49:39介绍Ubuntu 16.04纯文本界面、图形化界面切换方法 -
linux安装图形化界面以及卸载图形化界面
2019-08-03 09:42:36linux安装图形化界面 1、查看电脑是否联网 1.1、输入命令 ping www.baidu.com 没有返回字节的就是没有联网。 如果未联网进行1.2,如果已经联网请进行2即可,因为我在安装的时候已经把网络打开了,所以我的是已经... -
VirtualBox 图形化界面
2019-08-03 17:30:13一、安装图形化界面: 方法1:直接下载一个含有图形化界面的镜像,安装好; 方法2:在已经安装好的不带有图形化界面的虚拟机中联网自动下载图形化界面的软件,并自动安装好(注意一定是联网才能下载,关于联网问题... -
Centos7如何安装图形化界面 and 设置开机默认进入图形化界面
2018-03-24 17:08:51因为VMware安装虚拟机的时候默认是最小安装的,所以没有图形化界面,这样将本机文件转移到虚拟机上的时候特别不方便。而装好图形化界面之后只需在本机复制(crtl+c),然后在虚拟机中对应位置右键paste即可。1.打开... -
Win10安装Ubuntu子系统及图形化界面详细教程
2019-02-28 09:40:22打开Microsoft Store,搜索Ubuntu,出现如下界面: 选择我红框框出来的两个版本,不要选第一个,那个有坑。安装速度还是挺快的。 安装完了之后会在开始菜单出现linux的bash: 打开之后还需要继续安装一小会..... -
linux的命令行界面下安装图形化界面
2018-10-23 10:32:54在安装操作系统时若安装了图形化界面的软件包:只需输入命令“startx”启动图形化界面即可。 在虚拟机上安装操作系统时未安装图形化界面时如下: 由于未安装图形化界面所需的软件包,故安装完成后默认是命令行... -
图形化界面-0819
2020-08-21 11:01:22蓝杰培训——图形化界面(界面的交互功能)目录初始化图形化界面设计交互功能 目录 初始化图形化界面 这部分是图形化界面的代码 package cz0819; import javax.swing.JFrame; public class login { /** * 图形化... -
Python 图形化界面设计
2019-05-30 21:40:241、图形化界面设计的基本理解 当前流行的计算机桌面应用程序大多数为图形化用户界面(Graphic User Interface,GUI),即通过鼠标对菜单、按钮等图形化元素触发指令,并从标签、对话框等图型化显示容器中获取人机对话... -
Java 图形化界面的实现
2020-11-10 22:44:22Java 图形化界面的实现 1.图形化界面实现所需的条件 图形化界面的窗体,图形化界面的面板 2.界面的窗体 2.1 什么是图形化界面的窗体 如图,黑色的外边框就类似于图形化界面的窗体,要实现图形化界面,窗体是不可... -
Win10 任务管理栏 太宽问题的解决 及应用只有小图标没有图形化界面问题解决
2020-12-14 12:16:01在解决该问题的过程中,发现打开InteliJ idea的时候,只有任务栏的小图标,并没有图形化界面 背景是之前曾经在两个显示器上显示过,导致拖拽到其他显示器上,现在单个显示器不能显示 解决方式: win+D两次即可... -
linux命令行界面如何安装图形化界面
2018-02-06 11:56:16如何卸载图形化界面 遭遇问题 问题描述 当我们在安装Linux系统时,我们一开始可能安装的是非图形界面的系统,就是有可能选择的是最小化安装方式。这种安装凡是有很多的坑。那么有时候,我们可能需要进行... -
Raspberry Pi (树莓派) 图形化界面启动和命令行界面启动
2019-01-17 11:25:11Raspberry Pi (树莓派) 图形化界面启动和命令行界面启动 1. Raspberry Pi Configuration 1.1 Raspberry Pi Configuration - System Boot: To Desktop / To CLI To Desktop 启动到桌面系统。 To CLI 启动到命令行。... -
Xshell显示图形化界面
2017-12-03 12:51:50很久没用过图形化界面了,都忘记怎么使用了。。。。 依据以往的经验都是由环境变量DISPLAY设置,然后就能连接了,每天也是匆匆忙忙的就过了一天,都不知道干了啥,分配的时间也少,但是一直纠结,进行各种设置... -
阿里云 CentOS7 安装图形化界面 。安装图形化界面看这一篇就够了。
2020-06-05 14:28:42在这之前想过两种方法来解决服务器无图形化界面,来操作eclipse。 1、在主机上下载eclipse把需要编译的代码编译成jar包导入服务器 2、在云服务器上装桌面环境 第一个想法验证失败,希望各位大佬能给与解决的方案 ... -
关于c++图形化界面的有关问题 怎么添加按钮的事件呢?刚接触c++对图形化界面还不是了解
2016-06-06 14:42:38怎么添加按钮的事件呢?刚接触c++对图形化界面还不是了解 怎么添加按钮的事件呢?刚接触c++对图形化界面还不是了解 怎么添加按钮的事件呢?刚接触c++对图形化界面还不是了解 -
虚拟机安装图形化界面
2020-07-18 08:43:36虚拟机安装图形化界面 1.第一步:下载的时候中途会提示 是否需要下载 输入 y 确认就好。第二步同 yum groupinstall ‘X Window System’ 2.第二步,这一步需要比较久,大概有一个多G的文件要下。耐心等待一会儿 ... -
linux命令行安装图形化界面
2019-11-05 10:11:12当初在装系统的时候装的是最小化安装,但因为某些原因 需要用到图形化,但又不想重装系统...2、因为图形化有很多组建,所以这里需要用组安装,执行命令:yum -y groupinstall GNOME Desktop 安装图形化界面需要安装... -
Linux命令行安装图形化界面
2021-01-27 08:59:58Linux命令行安装图形化界面 作者:刘国凯 ## 最小化安装 Linux安装向导界面,在"软件选择"中选择"最小安装" {#linux安装向导界面在软件选择中选择最小安装 .list-paragraph} 安装完成后重启,进入命令行界面 ... -
vue ui 使用图形化界面
2020-05-15 20:25:00你也可以通过vue ui命令以图形化界面创建和管理项目: vue ui 上述命令会打开一个浏览器窗口,并以图形化界面将你引导至项目创建的流程。 ... -
Centos7设置图形化界面或命令行界面
2019-08-11 11:27:35在图形化界面使用 Ctrl+alt+F2 切换到命令行界面 在命令行界面输入 init 5 切换到图形化界面 检查当前默认设置: graphical.targe: 开机进入图形界面 multi-user.target:开机进入命令行界面 [root@centos01... -
Centos7关闭图形化界面
2018-07-25 09:23:581.关闭图形化界面 systemctl set-default multi-user.target 2.开启图形化界面 systemctl set-default graphical.target