Python+Eric+PyQt 可视化编写Python界面程序的套件,Eric相当于IDE结合PyQt布局,安装教程和使用方法Google很多,这里就不说了。
下面记录在使用中遇到的一些概念和问题,有的问题查了好久:
1、注册事件和响应事件,在PyQt中叫做信号(singal)与槽(slot),信号:当某个对象的某个事件发生时,触发一个信号,槽:响应指定信号的所做的反应,其实信号槽类似于.NET里面的委托、事件,比如Repeater控件类,当行数据绑定后,触发一个ItemDataBound事件,不管使用者使用会监听该事件并做额外处理,其控件类内部都会触发该事件,这种机制很多程度提高了类的封装性和完整性。
2、布局和事件分离,Eric对指定ui选择右键,Compile form编译ui文件,生成对应的布局py文件(默认以UI_开头),这是布局界面,直接运行就可以看到在PyQt中的布局效果。如果要添加响应事件,需要右键ui文件,Generate Dialog code用于生成事件处理的py文件,点击后会弹出对话框,添加类名,选择需要处理的控件及其响应的事件,回车则生成了对应的方法。之后只需要在对应的方法写逻辑即可。
3、事件响应有两种方式,一种是使用指定的名称(运行时会自动执行到此),一种在__init__中绑定事件。如(两种都用会先执行on_btn_clicked再执行add):
def __init__(self, parent = None): """ Constructor """ QDialog.__init__(self, parent) self.setupUi(self) QtCore.QObject.connect(self.btn, QtCore.SIGNAL(_fromUtf8("clicked()")), self.add) def add(self): self.line.setText("sss") @pyqtSignature("") def on_btn_clicked(self): """ Slot documentation goes here. """ self.line.setText("mms")
4、事件不响应,写事件py文件是继承自原始UI文件的,设置事件后需要在运行新的py文件,而这个文件没有__main__块,于是我从原来UI文件中把__main__拷贝过来,修改了类名称。运行,发现,所有的事件都不响应,原以为是setText方法写错了,但怎么改也不对,最后再网上找到一个demo,发现在新的文件中去掉两行代码即可,如:
if __name__ == "__main__": import sys app = QtGui.QApplication(sys.argv) Dialog = QtGui.QDialog() #在继承中这一行不要 ui = Ui_Dialog() ui.setupUi(Dialog) #在继承中这一行不要 Dialog.show() #直接使用ui.show() sys.exit(app.exec_()) #以下是正确代码 if __name__ == "__main__": import sys app = QtGui.QApplication(sys.argv) ui = Dial() # 继承的类名 ui.show() sys.exit(app.exec_())
5、关于QListView如何添加Item的问题,Google一上午都没找到答案,大部分关于Qt的使用都是C++,而PyQt是Qt的一个Python版本,网上资料比较少。最后发现:
QListView是基于Model,而QListWidget是基于Item。这是它们的本质区别。 往QListView中添加条目需借助QAbstractListModel QListWidget 继承自 QListView listview是一种常见的view模型,用于QT中的mv模式,但这样有时候不方便,所以有了qlistwidget,这样的话,用起来方便些。用下列方式使用:
item = QtGui.QListWidgetItem(self.listView) item.setText(self.lineEdit.text())QListViewItem也搜到过,但是使用总是有问题,后来改成Widget就ok了。
6、还有一个问题就是,使用Eric写Python代码时,发现很多方法都不提示,使用PyDev就可以,不知道是不是没设置好。
7、显示最大化最小化:
self.setWindowFlags(self.windowFlags() & Qt.WindowMinMaxButtonsHint)
8、找问题找很久,还不如查查文档,虽然是英文的,效率也比瞎找高,PyQt似乎没有什么完整的文档,Qt的文档很全,由于PyQt是Qt的Python移植版本,就参考Qt文档来看吧:文档
9、设置Spliter(分割器),如果想拖动窗口内的控件修改大小,只需要设置QSpliter。设置方法:选中两个以上控件,右键,布局->垂直|水平分割器。
10、添加状态栏,状态栏和分割器一样,不能再控件区内找到。直接右键主窗口->添加状态栏即可,最后再代码里面创建QLabel,使用statusBar.addWidget(label)就添加上了。注意,只有MainWindow才可以用这种方法添加状态栏。
11、QListWidget删除一条Item使用takeItem(index),而不是remove。
12、QTableWidget设置某Item的宽高使用setColumnWidth(ci,wid)和setRowHeight(ri,hei)。如果要在item显示图片,使用item.setData(1, QPixmap(path)),第一个参数表示要设置的类型,第二个是设置的数据。参数一描述如下:
Constant | Value | Description |
---|---|---|
Qt::DisplayRole | 0 | 普通文本(QString) |
Qt::DecorationRole | 1 | 图片数据 (QColor,QIcon or QPixmap) |
Qt::EditRole | 2 | 编辑文本 (QString) |
Qt::ToolTipRole | 3 | 工具栏提示文本 (QString) |
Qt::StatusTipRole | 4 | 状态栏显示数据 (QString) |
Qt::WhatsThisRole | 5 | “这是什么?” 模式 (QString) |
13、获取滚动条并移动滚动条的位置,调用方法verticalScrollBar()和horizontalScrollBar()能获取垂直和水平滚动条,再使用setValue(value)设置当前值,使用setMaximum(value)设置最大值。
14、中文编码在任何编程语言中,都是个非常大的问题,根源就是从内存到外存过程中,存储编码的不一致。Qt从界面获取text,设置text的过程中,如果没有考虑好,很容易出现乱码。下面是我使用的简单解决办法,可能有更好的:
def decode_file(self, string): '''编码py文件中的汉字''' return string.decode("utf-8") def decode_text(self, string): '''编码从空间中读取的text''' return unicode(string) # 使用方法,在类里面定义的方法,所有有self # 1、将label显示为“正在加载,请稍后。” self.label.setText(self.decode_file("正在加载,请稍后。")) 或 self.label.setText(u"正在加载,请稍后。") # 2、获取contentEdit的文本 content = self.decode_text(self.contentEdit.text())