PyQt 4 显示多幅图像,并编辑打包

来源:互联网 发布:淘宝拍卖玉石是真的吗 编辑:程序博客网 时间:2024/05/16 15:17

PyQt 4 显示多幅图像,并编辑打包

最近在做单个字符图像分类的工作,大概有7000类,每个类别中的图像不等,共200W幅图像。训练之前有个问题,每个类别中的字符图像并不一定是正确的,需要把所有图像都检查一遍。工作量很大,做了个工具,希望能使工作简化下。

工具的目的:遍历所有图像,正确的留下。错误的删除或者编辑后放到正确的类别中。很简单了,但是第一次用PyQt,所以过来嘚瑟下~先看下界面截图:
ImageShow

很简单吧,左边的列表是所有类别的文件夹名,右边的就是当前类别中的图像,一次显示100幅。可以修改和删除。

工具是用Python 2.7 + PyQt4 实现的。网上的资料不少,也不算多,基本是参考PyQt4精彩实例完成,然后就是官方文档了。

图像的显示是用 “QToolButton” + “QGridLayout”实现的。在实现的过程中也遇到不少问题,现在也不太记得了,只能尽量列一部分吧。

1. QListWidget的点击事件

self.List_fileName.itemClicked.connect(self.list_itemClick)

这块研究了好久,一直不太清楚如何将List的item传递到响应函数中。通过上面的itemClicked其实是可以直接把item传递下去的,所以调用的时候就简单了,如

def list_itemClick(self,item):    curItem = str(item.text())    #可以对item中的内容进行操作了

2. 不同类之间的参数传递

在这个工具中,主窗口是用的QMainWindow类,如果把所有的功能都写到这个类中,其实就不存在参数传递的问题了。但是那样的话,这个类真的很长(现在的也不短…)。所以又增加了个QWidget的类,专门显示图像,即QToolButton。
实际上主窗口调用其他的类,可以直接调用的时候添加参数。如

#主窗口class ShowImgsWindow(QMainWindow):    def __init__(self,parent = None):    #调用的时候就跟调函数一样    self.ImgGrid_click = showImgsGrid(img_info)#QWidget类class showImgsGrid(QWidget):    def __init__(self,img_info,parent = None):    #这里的 img_info 就是参数

那问题是如何将QWidget类中的响应传到主窗口中去呢?比如该工具中,某个图片被点击了,图片会有信息(主要是文件名),这个信息如何传到主窗口中用于编辑or删除呢?参考过CSDN的blog和Stockflow上的讨论,只是暂时找不到链接了,等以后补上吧。
PyQt中有emit和pyqtSignal的方式来人为的传递参数,直接贴代码吧:

class showImgsGrid(QWidget):    #list表示传递的参数是list格式    toolBtn_clcEvent = pyqtSignal(list)    def __init__(self,img_info,parent = None):        .......        toolBtn = QToolButton()        toolBtn_img.clicked.connect(lambda:self.showEditDialog(file_name))    def showEditDialog(self,file_name):        sending_btn = self.sender()        objName = str(sending_btn.objectName())        text_unic = str(file_name)        self.toolBtn_clcEvent.emit([objName,text_unic])        #传递参数

在主窗口中

    self.ImgGrid_click = showImgsGrid(img_info)    #将传递的信号连接上处理函数    self.ImgGrid_click.toolBtn_clcEvent.connect(self.updateEditInfo)def updateImgNames(self,img_name):    #img_name就是传递过来的参数

详细的参考附件里面的源代码吧。这里面还有一个lambda调用参数的方式,就不详细介绍了。

3. Pyinstaller进行代码打包

这个网上的资料也不少哈,遇到的问题跟另外一篇blog中的问题差不多,PyQt发布成应用程序中遇到的若干问题。可以看下,QString的类型问题啊,被它折磨的要死要死的。

E:\TestPython\package>pyinstaller -F -w -p D:\SoftWare\Anaconda2X86_27\envs\py27\Lib;D:\SoftWare\Anaconda2X86_27\envs\py27\Lib\site-packages;D:\SoftWare\Anaconda2X86_27\envs\py27; test.py

这是我打包的命令,

  1. -F 是指把所有文件都打包到一个exe中
  2. -w 是指打包的是widget代码
  3. -p 是指定的搜索路径,其实没太大必要列出来

还有其他命令,就不列举了~
对了,还有一个问题:生成exe文件后,会出现内存泄露的问题。参考stackflow上的一个回答,解决方案:
在主窗口类中添加:

def cleanUp(self):    for i in self.__dict__:        item = self.__dict__[i]        clean(item)

在类的外层加函数:

def cleanUp(item):    if isinstance(item,list) or isinstance(item, dict):        for _ in range(len(item)):            clean(item.pop())    else:        try:            item.close()        except (RuntimeError, AttributeError):            pass        try:            item.deleteLater()        except (RuntimeError, AttributeError):            pass

最后,在程序的主函数中添加

app.aboutToQuit.connect(main.cleanUp)

在这个工具中呢,内存泄露的问题就解决了。

其实我也还有挺多问题不懂的,如果有什么问题,欢迎讨论。

附上源码了。

1 0