任务简介

因为项目要求,先需要设计一个软件界面。业务逻辑主要是基于深度学习实现图像的自动文字描述。界面主要要包括基本的菜单栏、待处理图像的展示、文字生成结果展示、图像批次切换按键等。

任务的难点主要是业务逻辑部分的模型加载、图像处理等操作都非常耗时,如果都放在界面代码里实现则可能会导致界面无响应。而PyQt的语法可以很方便地实现业务逻辑和界面程序的分离,并且能够很容易地将耗时任务放到多线程中处理。

目前已经完成初步版本,近期会开源到github上。

遇到的一些问题

由于刚刚接触PyQt,对于一些细节理解不深,因此在完成程序的过程中遇到一些问题,在此记录。

PyQt中多线程的实现方式主要是基于QThread类构建自定义的线程类,然后在该类中实现run()函数。在使用该类时,调用其start()方法即会启动新线程,并运行run()函数。在run()函数运行完成后线程就基本结束了。而需要注意的是,该线程类中其他的方法,包括init方法,都是在界面线程中执行。我因为不清楚这一点,出了很多错误,界面日常卡死。。。还曾经愚蠢地试图在线程类中定义public变量以在界面代码中与run函数通信(事实上,当run函数开始执行,init方法中的变量发生变化,并不能影响到run函数中对应的变量)

除此之外,界面线程和业务线程之间的通信主要基于PyQt的信号与槽机制。由于需要通信的信息量比较大(主要是线程加载的网络模型参数,大概几百兆),所以仔细研究了信号与槽机制的内存开销。通过查看信号机制发射的信号和槽接收到的信号的各自的内存地址,可以发现二者相同,也就是说这种信号与槽的通信机制传递的只是内存地址,类似函数的形参(?)。在连接信号与槽时,需要定义传递的内容的类型,由于只传递内存地址(指针?),所以可以直接传递复杂类的基类类型(这一点对于本任务非常重要。。因为可能会加载不同的网络模型结构)。