PySide——Python图形化界面入门教程(六)

            ——QListView和QStandardItemModel

翻译自:http://pythoncentral.io/pyside-pyqt-tutorial-qlistview-and-qstandarditemmodel/

上一个教程中,我们讨论了Qt的QListWidget类,它用来实现简单的单列列表框(list boxes)。然而,我们还需要更加灵活的widget来实现列表,Qt为此提供了QListView 来实现多种多样的项。它是一个纯粹的显示部件,用来显示数据模型提供的信息。这样做将将显示功能和数据逻辑分离开来;这同时还有一些其他widget可以显示来自同一模型结构的数据。

这里已经有一些创建好的几种类型的模型。比如,QStandardItemModel提供了比上一节QListWidget更棒的能力;拿文本和图标来说,它提供了拖拽的能力、checkable items和其他一些特性。自定义行为可以通过QAbstractlistModel继承实现——列表数据的通用模型。

PySide的QStandardItemModel

我们首先从讨论QListView来开始。QListView可以像其他的QWidget一样进行实例化——你是不是对每次讲一个widget都说这句话感到厌烦了?虽然有些啰嗦,但是让我们清晰的记得对象模型;PyQt/Pyside最优秀的地方就是它的简单、好记和继承性。这就是说,QListView构造器接收一个可选的参数parent:

list = QListView(parent)

现在我们的列表需要一个模型来管理它的数据。以我们的列表作为parent参数创建一个QStandardItemModel:

model = QStandardItemModel(list)

QStandardItemModel还有其他一些构造器,但是和我们的单列列表无关,我们有时间再来讨论。

PySide的QStandardItem

创建列表和模型是最简单的部分;列表的主要任务创建并嵌入模型。例如,我们先创建一个项:

item = QStandardItem()

方便地设置它的文本和图标:

item.setText('Item text')
item.setIcon(some_QIcon)

我们也可以让项目变成多选的,这将在项目的最左边添加一个复选框(checkbox)

item.setCheckable(True)

你还可以让复选框有三种状态——checked,unchecked,和null,使用

item.setCheckable(True)。
 
 

一个简单的QStandardItem例子

我们现在已经了解了QListView足够的背景,尽管它还什么都不能做。我们让QListView成为主窗口来尽可能的简化,就像其它任何QWidget作为主窗口的例子一样进行最基本的设置:

 list = QListView()
list.setWindowTitle('Example List')
list.setMinimumSize(600, 400)

接下来创建我们的模型:

model = QStandardItemModel(list)

然后我们创建一些QStandardItem来填充我们的模型。就列出我们想要的吃的事物吧,每一个都有一个文本标题和复选框。

 foods = [
'Cookie dough', # Must be store-bought
'Hummus', # Must be homemade
'Spaghetti', # Must be saucy
'Dal makhani', # Must be spicy
'Chocolate whipped cream' # Must be plentiful
] for food in foods:
# Create an item with a caption
item = QStandardItem(food) # Add a checkbox to it
item.setCheckable(True) # Add the item to the model
model.appendRow(item)

最后,将模型应用至QListView,显示窗口运行app。

 list.setModel(model)
list.show()
app.exec_()

完整的例子代码如下:

 # Create a Qt application
app = QApplication(sys.argv) # Our main window will be a QListView
list = QListView()
list.setWindowTitle('Example List')
list.setMinimumSize(600, 400) # Create an empty model for the list's data
model = QStandardItemModel(list) # Add some textual items
foods = [
'Cookie dough', # Must be store-bought
'Hummus', # Must be homemade
'Spaghetti', # Must be saucy
'Dal makhani', # Must be spicy
'Chocolate whipped cream' # Must be plentiful
] for food in foods:
# create an item with a caption
item = QStandardItem(food) # add a checkbox to it
item.setCheckable(True) # Add the item to the model
model.appendRow(item) # Apply the model to the list view
list.setModel(model) # Show the window and run the app
list.show()
app.exec_()

运行的时候看上去像是这样:

添加简单的功能

让我们看看如何让带有QStandardItemModel的QListView来与用户交互。你或许想象每个QStandardItem都像一个QPushButton,当被选择、编辑、等等的时候都会发出信号。如果你这样想,就像我一样,那就错了!在QStandardItemModel中,有一个更加强大的信号——itemChanged(item)来说明发生了什么。就像你看到的那样,它把发生变化的项发送给槽,你需要检查项来知道发生了什么。虽然不完美,但它确是这样的。

你还可以使用模型的item方法来检查没有改变过的项,它返回指定行(从0开始)的项。(同样可接受单列、多列模型)

这还有许多信号来表现模型结构的改变;它们都是从QAbstractItemModel继承而来,我们会在讨论QAbstractItemModel主题时再来学习它们。现在的例子我们还不需要。

现在我们来让清单更甜蜜(honey-do,作者还是很幽默的,但是我翻译不出来^_^)一些。你使用列表登记已经购买了的项,当你完成时,窗口会关闭。首先,改变标题:

list.setWindowTitle('Honey-Do List')

然后,我们需要一个槽来连接模型的itemChanged信号。当然, 我们首先需要使用checkState方法检查发生变化的项是否被选中,来避免每次遍历项。如果已经选中了,我们再检查是否其他的都被选中;如果都被选中了(即你已经都购买了),则退出QApplication。

 def on_item_changed(item):
# If the changed item is not checked, don't bother checking others
if not item.checkState():
return i = 0 # loop through the items until you get None, which
# means you've passed the end of the list
while model.item(i):
if not model.item(i).checkState():
return
i += 1 app.quit()

然后,我们将信号和槽连接起来:

model.itemChanged.connect(on_item_changed)

完整的代码如下所示:

 # Create a Qt application
app = QApplication(sys.argv) # Our main window will be a QListView
list = QListView()
list.setWindowTitle('Honey-Do List')
list.setMinimumSize(600, 400) # Create an empty model for the list's data
model = QStandardItemModel(list) # Add some textual items
foods = [
'Cookie dough', # Must be store-bought
'Hummus', # Must be homemade
'Spaghetti', # Must be saucy
'Dal makhani', # Must be spicy
'Chocolate whipped cream' # Must be plentiful
] for food in foods:
# Create an item with a caption
item = QStandardItem(food) # Add a checkbox to it
item.setCheckable(True) # Add the item to the model
model.appendRow(item) def on_item_changed(item):
# If the changed item is not checked, don't bother checking others
if not item.checkState():
return # Loop through the items until you get None, which
# means you've passed the end of the list
i = 0
while model.item(i):
if not model.item(i).checkState():
return
i += 1 app.quit() model.itemChanged.connect(on_item_changed) # Apply the model to the list view
list.setModel(model) # Show the window and run the app
list.show()
app.exec_()

这是一个QListView的简单例子。它还可以做更多的事情,但是相同的模型同样也可以用于其他的widget。下一次,我们将看一些完全不同的东西,一个最让原作者兴奋的部件,QWebView,一个基于WebKit的可以解析HTML/CSS/XML/XSLT页面的控件。(话虽如此,但是下个教程不在Qt wiki的入门教程之列,所以我就先不进行翻译了,需要的读者可以查看原作者的原文http://pythoncentral.io/pyside-pyqt-tutorial-qwebview/)

一些感想:

对于初学者,更多的资料应该还是要参考https://wiki.qt.io/PySide_Tutorials,这一至六的教程就是翻译的PythonCentral的3至8部分,仅仅起到抛砖引玉的作用。在学习之前,我首先还是喜欢搜索中文的资料,因为毕竟母语接受的快一些。可是搜索中却发现优秀的中文教程太少了,而英文教程我感觉要清晰的多,能让我从0基础开始更好的理解PySide,而不是不知其所以然的简单操作步骤。正是这个原因,我边看边进行了翻译,希望能帮到更多新手入门。同时也希望出现更多优秀的中文教程,并有更多的人来翻译优秀的英文官方教程。最后,由于译者水平十分有限,不周之处还请谅解。

补充:

发现一个优秀的详细中文系列教程(不过好些是C++),敬佩豆子作者的精神:http://www.devbean.net/2012/08/qt-study-road-2-catelog/

Pyside的官方手册:http://pyside.github.io/docs/pyside/

By Ascii0x03

转载请注明出处:http://www.cnblogs.com/ascii0x03/p/5505439.html

最新文章

  1. Hadoop技巧系列索引
  2. JavaScript自动生成博文目录导航
  3. TYVJ 1117 BFS
  4. CentOs安装Scrapy出现error: Setup script exited with error: command ‘gcc’ failed with exit status 1错误解决方案
  5. 深入了解Activity-生命周期
  6. mysql基本数据类型(mysql学习笔记三)
  7. UVALive 6198 A Terribly Grimm Problem
  8. 从零开始学Hadoop系列之File System命令一
  9. 使用StreamReader与StreamWriter进行文本文件读写
  10. 字符相等(E - 暴力求解、DFS)
  11. 第八十四节,css布局小技巧及font-awesome图标使用
  12. cocoaPods打包的静态库
  13. VMware中克隆虚拟机出现eth0改变为eth1情况
  14. IDEA设置生成类基本注释信息
  15. [Swift]LeetCode748. 最短完整词 | Shortest Completing Word
  16. Call to a member function display() on a non-object问题的解决
  17. [Ting's笔记Day8]活用套件carrierwave gem:(3)Deploy图片上传功能到Heroku网站
  18. 计时器---JS
  19. GitHub万星的ML算法面试大全
  20. Spring <context:annotation-config> 和 <context:component-scan> 区别

热门文章

  1. [Vue] Use basic event handling in Vue
  2. kali 系统的源
  3. Java 类锁、对象锁、私有锁
  4. iOS 简单的描述KVO使用
  5. 64位Oracle11g自带的sqldevelper无法启动
  6. KDE 邀请用户测试 Plasma Mobile 的首个专用 ISO 镜像(可以考虑做一个极客。。。)
  7. Android 升级下载 它们的定义Updates 兼容版本
  8. DapperPoco
  9. Java8初体验(二)Stream语法详解---符合人的思维模式,数据源--》stream-->干什么事(具体怎么做,就交给Stream)--》聚合
  10. Ibatis之RowHandler