背景:公司有个项目,需要一个夸平台的cs系统配合,由于公司的主要产品是用C#开放的,所以就这个项目就有python来完成。
简介:
PyQt是Qt库的Python版本,Qt库是目前最强大的GUI库之一,用C++编写,因此简单的说PyQt就是python封装的C++的GUI库。
安装:
由于要夸平台,因此需要在linux和windows下安装,windows上安装倒是没遇到什么问题,直接安装sip和pyqt的exe文件就行,但是在linux下(我用的ubuntu10.04),如果直接apt-get install pyqt4 是没有任何问题的。因为这种安装方式安装的pyqt不是最新的版本,因此,我选择了通过源码安装。
先安装sip
python configure.py
make
make install
在安装pyqt
python configure.py -q /usr/bin/qmake-qt4
make
make install
使用的遇到的问题:
1. 需要登录框,登录后跳到主界面

 1 from suds.client import Client
2 from PyQt4.QtCore import *
3 from PyQt4.QtGui import *
4 try:
5 import json
6 except:
7 import simplejson as json
8 class LoginWindow(QDialog):
9 def __init__(self, parent=None):
10 super(LoginWindow,self).__init__(parent)
11 self.setWindowTitle(u'登录')
12 self.setWindowFlags(Qt.WindowMinimizeButtonHint|Qt.WindowCloseButtonHint)
13 icon = QIcon('logo.png')
14 self.setWindowIcon(icon)
15
16 username_label = QLabel(u"用户名:")
17 self.username = QLineEdit("")
18
19 password_label = QLabel(u"密码:")
20 self.password = QLineEdit("")
21 self.password.setEchoMode(QLineEdit.Password)
22
23 button_login = QPushButton(u"登录")
24 button_login.setFixedWidth(80)
25 button_cannel = QPushButton(u"取消")
26 button_cannel.setFixedWidth(80)
27
28 layout = QGridLayout()
29 layout.addWidget(username_label,0,0)
30 layout.addWidget(self.username,0,1)
31 layout.addWidget(password_label,1,0)
32 layout.addWidget(self.password,1,1)
33 layout.addWidget(button_login,2,0)
34 layout.addWidget(button_cannel,2,1)
35
36 self.setLayout(layout)
37 self.setFixedSize(350,200)
38 self.move(400,400)
39
40 self.connect(button_login,SIGNAL("clicked()"),self.login)
41 self.connect(button_cannel,SIGNAL("clicked()"),self.close)
42
43 def login(self):
44 logined = True
45 client = Client(settings.USER_LOGIN_SERVICE)
46 message = client.service.Login(self.username.text(),self.password.text())
47 status = json.loads(message)
48 logined = status['status'] == 1
49 if not logined:
50 QMessageBox.information(self,u"提示",u"不存在这个用户或者用户名密码不匹配!")
51 else:
52 self.accept()
53
54 def get_username(self):
55 return self.username.text()
56 def get_password(self):
57 return self.password.text()

这样,一个登录框接完成了,接下来写一个主界面

class MainWindow(QDialog):
    pass

 接下来用login.exec_() == QDialog.Accepted来判断,如果成功登录,就跳到主界面

1 if login.exec_() == QDialog.Accepted:        
2 window = MainWindow()
3 window.show()

2. 信号和插槽,个人觉得这个还是比较难理解的
主界面上有一个按钮,绑定了一个很长时间的操作,类是与杀毒软件跟新病毒库,那么在这个操作之后,不能阻塞在这个地方,于是用到了QThread

 1 import time
2 class Worker(QThread):
3 def __init__(self):
4 QThread.__init__(self)
5 def run(self):
6 num = 10
7 self.emit(SIGNAL("start()"))
8 #初始化
9 time.sleep(1)
10 self.emit(SIGNAL("ready(int)"),num)
11 #准备
12 time.sleep(1)
13 for i in range(num):
14 self.emit(SIGNAL("process(int)"),i+1)
15 #处理过程
16 time.sleep(1)
17 #完成
18 self.emit(SIGNAL("terminated()"))
19 class SyncWindow(QDialog):
20 def __init__(self,rt_show_window, trayIcon, parent=None, ):
21 super(SyncWindow,self).__init__(parent)
22
23 button = QPushButton(u"开始")
24
25 self.notice_label1 = QLabel(u"扫描所需下载的压缩包中")
26 self.notice_label2 = QLabel(u"解压压缩包,解析xml并入库中")
27 self.notice_label1.setVisible(False)
28 self.notice_label2.setVisible(False)
29
30 self.progressBar = QProgressBar()
31 self.progressBar.setVisible(False)
32
33 self.thead_insert = Worker()
34 self.connect(self.thead_insert,SIGNAL("start()"), self.update_label1)
35 self.connect(self.thead_insert,SIGNAL("ready(int)"), self.update_label2)
36 self.connect(self.thead_insert,SIGNAL("terminated()"), self.update_label3)
37
38 self.connect(self.thead_insert,SIGNAL("process(int)"), self.process)
39
40 self.connect(button,SIGNAL("clicked()"),self.thread_sync)
41
42 def update_label1(self):
43 self.notice_label1.setVisible(True)
44
45 def update_label2(self,num):
46 self.notice_label1.setVisible(False)
47 self.notice_label2.setVisible(True)
48
49 self.progressBar.setMinimum(0)
50 self.progressBar.setMaximum(num)
51 self.progressBar.setVisible(True)
52
53 def update_label3(self):
54 self.notice_label2.setVisible(False)
55 self.progressBar.setVisible(False)
56
57 def process(self,setup):
58 self.progressBar.setValue(setup)
59
60 def thread_sync(self):
61 self.thead_insert.start()

 上面是一个简写的代码,目的就点击这个操作的时候,需要显示现在更新的状态。
点击button,开启一个线程,就调用Worker的run方法,而在run里面一定的插槽emit,代码执行到self.emit(SIGNAL("start()")),就会调用self.connect(self.thead_insert,SIGNAL("start()"), self.update_label1)所绑定的update_label1的方法,这样就把信号过来过去的,很有意识。


3. 就是界面的布局,界面大小,位置等问题,这个了解的不是很深,基本上需要就在网上找。