最近几天在需要做个人脸检索的demo,开始在考虑使用C或者Python,但是由于我之前的实验使用的是基于Python的Keras框架,所以选择使用Python来做GUI,Python的GUI工具很多,wxPython,Flexx或者PyQt,因为之前挺想试试Qt的,所以就选择使用PyQt来做最后的demo。最新的Qt有4和5两个版本,如果使用的话,我还是比较建议使用4,第一是网上的教程相对较多,第二就是安装。。。。。我这次是在windows下安装的PyQt,官网上4的安装有专门的exe安装包,对windows来说十分友好,如果使用PyQt5的话,还得安装其他的东西,有点麻烦。最后我选择的版本如下图,在官网上都能找到。
IDE上我试了一下传说中的Eric感觉也一般,最后我还是使用Pycharm,具体IDE配置Qt的步骤参考IDE配置Qt。别看说的那么轻松,其实安装废了老鼻子劲了(~ ̄▽ ̄)~,这里有个PyQT4的教程推荐给大家PyQt4教程。下面来给大家说说路上爬的坑。。。
我的目的是要做一个人脸检索的demo,所以图片的展示就必不可少了,这个百度一下就可以发现,在Qt下可以使用QLabel来显示图片,不管是jpg,bmp还是png我都替大家试过了,都是可行的,这时候最好的方式就是放个代码了:
import sys
from PyQt4 import QtGui
class Example(QtGui.QWidget):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
label = QtGui.QLabel(self)
label.setScaledContents(True)
image = QtGui.QImage()
image.load('./img/2_0.jpg')
label.setPixmap(QtGui.QPixmap.fromImage(image))
self.resize(image.width(),image.height())
app = QtGui.QApplication(sys.argv)
ex = Example()
ex.show()
sys.exit(app.exec_())
label.setScaledContents(True)用来将label给resize成图片大小,免得遮挡,QLabel可以通过载入QImage类来生成QPixmap类从而显示图片,最后把窗口也resize成图片大小。这里有一点,任何没有继承其他对象的QWidget类都是可以 直接show的,如果QWidget a继承了QWidget b,也就是作为了b的子类(a(b)),a就没法show了。
图片的展示很简单,只有因为图片太多,想做个滑动条,但是滑动条一直没法显示,之后甚至连图片都没法显示,网上的资料很多,但是说的都不够详细,下面直接放我的代码再港:
class Example(QtGui.QWidget):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
self.resize(800, 540)
self.a = QtGui.QWidget(self)
self.a.setMinimumSize(800, 1500)
self.scroll = QtGui.QScrollArea(self)
self.scroll.setWidget(self.a)
self.v = QtGui.QGridLayout(self)
self.v.addWidget(self.scroll)
self.show()
app = QtGui.QApplication(sys.argv)
ex = Example()
ex.show()
sys.exit(app.exec_())
这里有几点需要注意一下,首先setMinimunSize必不可少,这是使用滑动条的基础,就是让显示窗口scrollarea远小于真实界面a,你只能移动窗口看,所以才需要滑动条,这个值要比你的界面大。因为a和scroll都是self的子类,然后可以将scroll放置在a上,也就是真实窗口上。self.v = QtGui.QGridLayout(self)和self.v.addWidget(self.scroll)也可以换成self.scroll.resize(800, 540),只是界面有一些不同,这样就可以显示滑动条了。
后来在通过一个窗口Mainwindow调用另一个窗口anotherwindows的过程中出现了要调用的窗口一闪而过的情况,仔细思考就可以发现,其实是在新窗口中,并没有将anotherwindows赋成成员变量(self.anotherwindows),非成员变量在类成员函数结束后就被释放了,所以窗口也就一闪而过了,所以将成员赋值为成员变量就好了。