基于python tkinter开发的截图ocr GUI程序【含源码】

图文精灵2.0

程序框架

在这里插入图片描述
按模块功能分别来看关联的tkinter知识点,这里会挑一些需要重点注意的点来叙述

历史记录模组

如何实现滑动窗口

canve组件

self.canvas= tk.Canvas(self.window,width = WinWidth,height=WinHeight, scrollregion=(0,0,WinWidth,WinHeight-pad)) #

self.fm1 = ttk.Frame(self.canvas)
self.vbar=tk.Scrollbar(self.canvas,
                  orient=tk.VERTICAL,
                  command=self.canvas.yview,
                  width=5) 
self.canvas.config(yscrollcommand= self.vbar.set,bg="white",selectforeground="white",highlightthickness = 1)
       
self.canvas.place(x = 0, y = pad,width=WinWidth,height=WinHeight-pad) #放置canvas的位置  
self.vbar.place(x = 215,y= (-pad),width=5,height=(WinHeight+pad))
self.canvas.create_window(((0,0)), window=self.fm1,anchor='nw')  #create_window  

可以观察到写法为创建一个canvas,然后将布局frame,加入到这个canvas中,之后frame中的小组件都会在canvas这个窗口上被浏览,控制浏览窗口的方法为Scrollbar,滑动条,这个如果直接使用看起来会比较丑,所以可以在设计时可以将上下隐藏进canvas视窗外部
在这里插入图片描述

冻结窗口

使用该接口的目的为消除顶部按键,并且组件无法被选中并移动,很符合不需要用户拖动的窗口设计

self.window.overrideredirect(True)

子窗口对齐

x = max(self.root.winfo_x()-WinWidth,0)
y = max(self.root.winfo_y(),0)
self.window.geometry('%dx%d+%d+%d' % (WinWidth, WinHeight,x,y))

以上功能为获取父窗口位置,水平左侧放置,如果超出屏幕范围,显示在屏幕最左侧

绑定鼠标滚轮

self.canvas.yview_scroll(int(-1*(event.delta/120)),"units") 

event.delta/120 此处的除以120是windows下的滚轮速度,是120的倍速
mac和linux不需要除以这个倍数,至于-1*是鼠标滚轮反转,看个人习惯进行配置,玩FPS应该都知道的

更新canvas(非常关键)

def updateCanvas(self,event):
        """铺满当前画布 少了这个就滚动不了"""
        height = self.fm1.winfo_height()
        if(height > (WinHeight-40)):
        	#当内容不足以达到canvas高度时滚轮不使能
            self.canvas.bind_all("<MouseWheel>",self.WheelCtrl)
            self.canvas.configure(scrollregion=self.canvas.bbox("all"),width=WinWidth,height=200)
        pass
self.fm1.bind("<Configure>",self.updateCanvas)

该函数用于保证 Frame 中的内容只要被更改,就会触发Canvas重新绑定全局

主界面

Frame布局

 def display(s):
        """显示布局"""
        #Frame1
        s.B.pack(side=TOP,anchor=W,fill=X,expand=N)
        s.G.pack(side=TOP,anchor=W,fill=X,expand=N)
        s.D.pack(side=TOP,anchor=W,fill=X,expand=N)
        s.Notice.pack(side=TOP,anchor=W,fill=BOTH,expand=Y)

        #Frame2
        s.OcrRes.pack(side=TOP,anchor=W,fill=X,expand=N) 
        s.Edit1.pack(side=TOP,anchor=W,fill=BOTH,expand=Y)
        
        s.TransButton.pack(side=LEFT,anchor=CENTER,fill=X,expand=Y)
        s.TransChoose.pack(side=RIGHT,anchor=W,fill=BOTH,expand=Y)

        #Frame3
        s.TransRes.pack(side=TOP,anchor=W,fill=X,expand=N) 
        s.Edit2.pack(side=TOP,anchor=W,fill=BOTH,expand=Y)

        s.fm1.pack(side=LEFT, fill=BOTH, expand=YES)
        s.fm2.pack(side=LEFT, fill=BOTH, expand=YES)
        s.fm3.forget()

pack几个参数解释一下,side堆叠的方向,anchor相对位置,fill填充,expand 总布局中是否扩展

子窗口指定位置

def showAbout(s):
        """显示关于"""
        AboutObj = tk.Toplevel(s.root)
        AboutObj.title("关于")
        AboutObj.attributes("-toolwindow", 2) # 去掉窗口最大化最小化按钮,只保留关闭
        Aboutwin_weight = 300
        Aboutwin_height = 210
        icon = tk.PhotoImage(file = "./res/image/256x256.png")
        AboutObj.Lb = ttk.Label(AboutObj,anchor='center',image=icon,text=About,foreground='grey', font=('Microsoft Yahei',8),compound="top")
        x = max(s.root.winfo_x(),0)
        y = max(s.root.winfo_y(),0)
        AboutObj.geometry('%dx%d+%d+%d' % (Aboutwin_weight, Aboutwin_height,x+(main_windowWidth-Aboutwin_weight)/2,y+(main_windowHeight-Aboutwin_height)/2))

        AboutObj.Lb.pack()
        AboutObj.focus_set()
        AboutObj.mainloop()

以上实现了一个居中于父窗口显示的子窗口

隐藏显示控件

s.root.withdraw() #隐藏窗口
s.root.deiconify() #显示窗口

使控件不可控

def changeTool_WithoutIntert(s,state):
       if(state == 1):
           s.B['state'] = 'normal'
           s.G['state'] = 'normal'
           s.D['state'] = 'normal'
           s.TransButton['state'] = 'normal'
       if(state == 0):
           s.B['state'] = 'disable'
           s.G['state'] = 'disable'
           s.D['state'] = 'disable'
           s.TransButton['state'] = 'disable'

normal 为可操作状态,disable 未不可控灰色状态,用于限制一些需要前置条件的操作

屏幕截图

屏幕截图我参考的是以下文章实现的
https://cloud.tencent.com/developer/article/1097904

值得说的一点是,获取屏幕分辨率这个函数默认是不受屏幕缩放影响的,所以在你改变缩放倍数时,有可能会导致错误,我的程序里面已经解决了这一问题,解决方法链接如下
解决Windows缩放Python获取屏幕分辨率问题

最小化到托盘

引用站内大佬文章实现:
SysTrayIcon 改的 python tkinter 最小化至系统托盘
有一点需要注意,最小化的时候不要去操作主界面的控件内容,会报线程错误

以上就这些需要特别说明的内容了

软件新增特性

  1. 在1.0的基础上加入了翻译结果的编辑框,用户可以在编辑框中直接编辑翻译结果后再复制到别处去
    在这里插入图片描述
  2. 支持将结果翻译为其他语言,对于一些会接触到外文内容翻译的情景可以在一个软件中集中处理在这里插入图片描述
  3. 支持识别历史内容记录,可以快速翻看并提取之前的记录信息
    在这里插入图片描述

还有其他一些小细节,待大家使用demo安装体验~

github仓库:https://github.com/Weeeendi/Picture2Text

开发者说

对开发者说:

这一次的 GUI 开发框架还是使用了 python 的 Tinkter 库进行开发,但是逐渐认识到了该框架的一些弊端,例如字符串入参这个真的是写的人很痛苦,每个函数写入参数时根本没有任何提示,只能去源码里面查注释,但有时注释也是看的人稀里糊涂,网上查相关资料也比较少,还有不同窗口里面调度内容也非常繁琐,必须要从根节点来访问各个控件,效率很低。优点就是生成的文件比较小,框架简单。
如果下次我再写 GUI 的工具应该会选择 pysider2 这类现代化的框架,该框架基于 QT 的 GUI 设计思想来设计 GUI,俗话说的好让专业的人来干专业的事是没错的,对于和几种 python GUI库的优劣势细节,某乎上有很好的回答,感兴趣的开发者可以自行探索,这里就不一一赘述了,本程序的全部代码会开源在github上,可以进行二次开发,对代码中有的功能看不太懂的可以联系我进行交流。
该工具作为开源软件,使用MIT协议,原版软件禁止任何形式的商业用途,可以在百度云注册自己的云端接口秘钥替换使用,开发文档有说明。

对使用者说:

开发的东西可以让爱好者自己看代码,但是在开发之外的事情,我要说的很多,意思就是接下来内容会很多,不想看的读者可以自行跳过。
起初开发这个软件是在2019年,只是为了解决我工作上的问题,能让我更快的将别处的信息纳入我的文字内容当中,因为打字速度是常常跟不上思想的,你从别处看到的一句有意思的话想收集起来,但是如果这个是在真实世界的物品上,要转变成为文字需要走好大一个圈,我希望我的工具可以缩短这个路径,也就是直接降低体力工作,打字确实是个体力活,这一点到今天仍然是不会改变的。
现在唯一遗憾的一点就是没有开发出手机端的软件,因为手机的摄像头更加易于采集图像,然后可以通过手机蓝牙或者数据线与电脑端同步历史记录,这应该是本软件的最终形态了,但其中涉及到的知识对于今天的我来说,就像徒步从海南走到西藏一样遥不可及,最让人感到退缩的是,我害怕我要独自走完这段路。
还有接触到 GUI 的开发后,作为第一个使用的人来开发软件,要考虑到很多问题,例如两个界面间的衔接是否流畅,软件使用逻辑是否易于理解,符合人的直觉,都是很重要的这些是超越技术的问题,需要更多的人文思考,综合来说就是产品逻辑。
在开发中我借鉴了很多其他软件好的部分,此时可能会有人说不就是抄吗,我个人也是反感跟风抄的,作为学习一门新技能的人,抄一直是我认为最好的学习方法,好在于能培养好的学习习惯,建立良好的知识体系,抄也是要比较的,比较保险的方法就是抄大公司的产品,和画画一样临摹别人的作品,学习优秀的作品会渐渐的让你在设计的时侯成为一种下意识的举动。
如果你能在不知道对方是如何实现的情况下,达到他的90%那我觉得你已经基本学会了这项技能,我的软件里面的历史记录功能抄的就是 windows 自带的历史粘贴板功能,可以在下面的动图中观察两者差异。

在这里插入图片描述

基本是一模一样的对吗,但是我是不可能知道微软的源码的,抄的要点是抓住骨架,经过我一帧帧的使用,能观察到的要点有 浮窗不可移动、没有边框、选中内容时高亮、失去焦点或选中内容后消失、下方会有使用提示。以上就是我对这个工具的初次认识,也就是我要模仿的骨架。最终实现的效果也是八九不离十的,这就是一次成功的学习。
最后我想说的是,在平台公司肆虐的今天,好像我们的一切都被他们安排好了,和父辈聊天,过去人工作是有价值感、社会认同感的,今天的工人们,我们有时自认为都是一个工具人,打工人,人被资源化了,工作的唯一价值就是换取工资,工作中创作的东西也并不归属于我们,我现在这份工作也是这样,我创造了价值吗,我是一个生产者吗,我常常这样质问自己,今天好像人作为消费者的时候才被认同,要不人们为什么只在晒去哪里旅游买了什么东西,很少有人认为今天所做的工作是激动人心的,是值得被铭记的,唯一为生产内容感到骄傲成了企业高管,少部分人的特权。不应该是这样的,这是我进行开源软件开发的初衷,一把锤子不应该因为它姓王还是姓李而被人铭记,被人津津乐道,而是因为它能够方便又高效的敲钉子。
开源软件就是这样,让工具成为工具本身,它属于每一个使用它的人,这是我认可的价值,记得有人说过

科技唯一的价值在于解决人类的苦难

我深以为然,生活中有很多能够书写个人价值的笔,开源是我找到的其中一支,哪怕现在我能做的很少,但这可以作为我终身的信条。

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值