﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-清源游民的网络笔记本</title><link>http://www.cppblog.com/yuanyajie/</link><description>记录所思所想，收藏所见所闻�?
</description><language>zh-cn</language><lastBuildDate>Sat, 30 Aug 2008 12:55:51 GMT</lastBuildDate><pubDate>Sat, 30 Aug 2008 12:55:51 GMT</pubDate><ttl>60</ttl><item><title>（网摘好文）C++多态技术的实现和反思</title><link>http://www.cppblog.com/yuanyajie/archive/2007/11/09/36260.html</link><dc:creator>清源游民</dc:creator><author>清源游民</author><pubDate>Fri, 09 Nov 2007 14:32:00 GMT</pubDate><guid>http://www.cppblog.com/yuanyajie/archive/2007/11/09/36260.html</guid><wfw:comment>http://www.cppblog.com/yuanyajie/comments/36260.html</wfw:comment><comments>http://www.cppblog.com/yuanyajie/archive/2007/11/09/36260.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cppblog.com/yuanyajie/comments/commentRss/36260.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/yuanyajie/services/trackbacks/36260.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;<a href='http://www.cppblog.com/yuanyajie/archive/2007/11/09/36260.html'>阅读全文</a><img src ="http://www.cppblog.com/yuanyajie/aggbug/36260.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/yuanyajie/" target="_blank">清源游民</a> 2007-11-09 22:32 <a href="http://www.cppblog.com/yuanyajie/archive/2007/11/09/36260.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>（网摘好文）关于野指针</title><link>http://www.cppblog.com/yuanyajie/archive/2007/11/09/36259.html</link><dc:creator>清源游民</dc:creator><author>清源游民</author><pubDate>Fri, 09 Nov 2007 14:21:00 GMT</pubDate><guid>http://www.cppblog.com/yuanyajie/archive/2007/11/09/36259.html</guid><wfw:comment>http://www.cppblog.com/yuanyajie/comments/36259.html</wfw:comment><comments>http://www.cppblog.com/yuanyajie/archive/2007/11/09/36259.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/yuanyajie/comments/commentRss/36259.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/yuanyajie/services/trackbacks/36259.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;<a href='http://www.cppblog.com/yuanyajie/archive/2007/11/09/36259.html'>阅读全文</a><img src ="http://www.cppblog.com/yuanyajie/aggbug/36259.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/yuanyajie/" target="_blank">清源游民</a> 2007-11-09 22:21 <a href="http://www.cppblog.com/yuanyajie/archive/2007/11/09/36259.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>还是关QSettings的，把我的问题重复一下</title><link>http://www.cppblog.com/yuanyajie/archive/2007/10/26/35276.html</link><dc:creator>清源游民</dc:creator><author>清源游民</author><pubDate>Fri, 26 Oct 2007 15:48:00 GMT</pubDate><guid>http://www.cppblog.com/yuanyajie/archive/2007/10/26/35276.html</guid><wfw:comment>http://www.cppblog.com/yuanyajie/comments/35276.html</wfw:comment><comments>http://www.cppblog.com/yuanyajie/archive/2007/10/26/35276.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.cppblog.com/yuanyajie/comments/commentRss/35276.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/yuanyajie/services/trackbacks/35276.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;<a href='http://www.cppblog.com/yuanyajie/archive/2007/10/26/35276.html'>阅读全文</a><img src ="http://www.cppblog.com/yuanyajie/aggbug/35276.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/yuanyajie/" target="_blank">清源游民</a> 2007-10-26 23:48 <a href="http://www.cppblog.com/yuanyajie/archive/2007/10/26/35276.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>用Qt的进来帮忙解决下有关QSettings中写入中文的问题</title><link>http://www.cppblog.com/yuanyajie/archive/2007/10/26/35188.html</link><dc:creator>清源游民</dc:creator><author>清源游民</author><pubDate>Thu, 25 Oct 2007 19:16:00 GMT</pubDate><guid>http://www.cppblog.com/yuanyajie/archive/2007/10/26/35188.html</guid><wfw:comment>http://www.cppblog.com/yuanyajie/comments/35188.html</wfw:comment><comments>http://www.cppblog.com/yuanyajie/archive/2007/10/26/35188.html#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://www.cppblog.com/yuanyajie/comments/commentRss/35188.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/yuanyajie/services/trackbacks/35188.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;<a href='http://www.cppblog.com/yuanyajie/archive/2007/10/26/35188.html'>阅读全文</a><img src ="http://www.cppblog.com/yuanyajie/aggbug/35188.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/yuanyajie/" target="_blank">清源游民</a> 2007-10-26 03:16 <a href="http://www.cppblog.com/yuanyajie/archive/2007/10/26/35188.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Connecting Signals to QtScript Functions(转)</title><link>http://www.cppblog.com/yuanyajie/archive/2007/10/07/33666.html</link><dc:creator>清源游民</dc:creator><author>清源游民</author><pubDate>Sat, 06 Oct 2007 16:20:00 GMT</pubDate><guid>http://www.cppblog.com/yuanyajie/archive/2007/10/07/33666.html</guid><wfw:comment>http://www.cppblog.com/yuanyajie/comments/33666.html</wfw:comment><comments>http://www.cppblog.com/yuanyajie/archive/2007/10/07/33666.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/yuanyajie/comments/commentRss/33666.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/yuanyajie/services/trackbacks/33666.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;<a href='http://www.cppblog.com/yuanyajie/archive/2007/10/07/33666.html'>阅读全文</a><img src ="http://www.cppblog.com/yuanyajie/aggbug/33666.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/yuanyajie/" target="_blank">清源游民</a> 2007-10-07 00:20 <a href="http://www.cppblog.com/yuanyajie/archive/2007/10/07/33666.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Say hello to QtScript!(转)</title><link>http://www.cppblog.com/yuanyajie/archive/2007/10/07/33665.html</link><dc:creator>清源游民</dc:creator><author>清源游民</author><pubDate>Sat, 06 Oct 2007 16:17:00 GMT</pubDate><guid>http://www.cppblog.com/yuanyajie/archive/2007/10/07/33665.html</guid><wfw:comment>http://www.cppblog.com/yuanyajie/comments/33665.html</wfw:comment><comments>http://www.cppblog.com/yuanyajie/archive/2007/10/07/33665.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cppblog.com/yuanyajie/comments/commentRss/33665.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/yuanyajie/services/trackbacks/33665.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;<a href='http://www.cppblog.com/yuanyajie/archive/2007/10/07/33665.html'>阅读全文</a><img src ="http://www.cppblog.com/yuanyajie/aggbug/33665.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/yuanyajie/" target="_blank">清源游民</a> 2007-10-07 00:17 <a href="http://www.cppblog.com/yuanyajie/archive/2007/10/07/33665.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>QT的Graphics View柜架(3/3) </title><link>http://www.cppblog.com/yuanyajie/archive/2007/09/27/32962.html</link><dc:creator>清源游民</dc:creator><author>清源游民</author><pubDate>Wed, 26 Sep 2007 16:09:00 GMT</pubDate><guid>http://www.cppblog.com/yuanyajie/archive/2007/09/27/32962.html</guid><wfw:comment>http://www.cppblog.com/yuanyajie/comments/32962.html</wfw:comment><comments>http://www.cppblog.com/yuanyajie/archive/2007/09/27/32962.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cppblog.com/yuanyajie/comments/commentRss/32962.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/yuanyajie/services/trackbacks/32962.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;<a href='http://www.cppblog.com/yuanyajie/archive/2007/09/27/32962.html'>阅读全文</a><img src ="http://www.cppblog.com/yuanyajie/aggbug/32962.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/yuanyajie/" target="_blank">清源游民</a> 2007-09-27 00:09 <a href="http://www.cppblog.com/yuanyajie/archive/2007/09/27/32962.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>QT的Graphics View柜架(2/3) </title><link>http://www.cppblog.com/yuanyajie/archive/2007/09/26/32961.html</link><dc:creator>清源游民</dc:creator><author>清源游民</author><pubDate>Wed, 26 Sep 2007 15:57:00 GMT</pubDate><guid>http://www.cppblog.com/yuanyajie/archive/2007/09/26/32961.html</guid><wfw:comment>http://www.cppblog.com/yuanyajie/comments/32961.html</wfw:comment><comments>http://www.cppblog.com/yuanyajie/archive/2007/09/26/32961.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/yuanyajie/comments/commentRss/32961.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/yuanyajie/services/trackbacks/32961.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;<a href='http://www.cppblog.com/yuanyajie/archive/2007/09/26/32961.html'>阅读全文</a><img src ="http://www.cppblog.com/yuanyajie/aggbug/32961.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/yuanyajie/" target="_blank">清源游民</a> 2007-09-26 23:57 <a href="http://www.cppblog.com/yuanyajie/archive/2007/09/26/32961.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>QT的Graphics View柜架(1/3)</title><link>http://www.cppblog.com/yuanyajie/archive/2007/09/26/32960.html</link><dc:creator>清源游民</dc:creator><author>清源游民</author><pubDate>Wed, 26 Sep 2007 15:49:00 GMT</pubDate><guid>http://www.cppblog.com/yuanyajie/archive/2007/09/26/32960.html</guid><wfw:comment>http://www.cppblog.com/yuanyajie/comments/32960.html</wfw:comment><comments>http://www.cppblog.com/yuanyajie/archive/2007/09/26/32960.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/yuanyajie/comments/commentRss/32960.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/yuanyajie/services/trackbacks/32960.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;<a href='http://www.cppblog.com/yuanyajie/archive/2007/09/26/32960.html'>阅读全文</a><img src ="http://www.cppblog.com/yuanyajie/aggbug/32960.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/yuanyajie/" target="_blank">清源游民</a> 2007-09-26 23:49 <a href="http://www.cppblog.com/yuanyajie/archive/2007/09/26/32960.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>QT中的对象树与对象拥有权</title><link>http://www.cppblog.com/yuanyajie/archive/2007/09/25/32854.html</link><dc:creator>清源游民</dc:creator><author>清源游民</author><pubDate>Tue, 25 Sep 2007 12:36:00 GMT</pubDate><guid>http://www.cppblog.com/yuanyajie/archive/2007/09/25/32854.html</guid><wfw:comment>http://www.cppblog.com/yuanyajie/comments/32854.html</wfw:comment><comments>http://www.cppblog.com/yuanyajie/archive/2007/09/25/32854.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/yuanyajie/comments/commentRss/32854.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/yuanyajie/services/trackbacks/32854.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;<a href='http://www.cppblog.com/yuanyajie/archive/2007/09/25/32854.html'>阅读全文</a><img src ="http://www.cppblog.com/yuanyajie/aggbug/32854.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/yuanyajie/" target="_blank">清源游民</a> 2007-09-25 20:36 <a href="http://www.cppblog.com/yuanyajie/archive/2007/09/25/32854.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>我的QT笔记打包下载</title><link>http://www.cppblog.com/yuanyajie/archive/2007/09/24/32795.html</link><dc:creator>清源游民</dc:creator><author>清源游民</author><pubDate>Mon, 24 Sep 2007 09:59:00 GMT</pubDate><guid>http://www.cppblog.com/yuanyajie/archive/2007/09/24/32795.html</guid><wfw:comment>http://www.cppblog.com/yuanyajie/comments/32795.html</wfw:comment><comments>http://www.cppblog.com/yuanyajie/archive/2007/09/24/32795.html#Feedback</comments><slash:comments>16</slash:comments><wfw:commentRss>http://www.cppblog.com/yuanyajie/comments/commentRss/32795.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/yuanyajie/services/trackbacks/32795.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;<a href='http://www.cppblog.com/yuanyajie/archive/2007/09/24/32795.html'>阅读全文</a><img src ="http://www.cppblog.com/yuanyajie/aggbug/32795.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/yuanyajie/" target="_blank">清源游民</a> 2007-09-24 17:59 <a href="http://www.cppblog.com/yuanyajie/archive/2007/09/24/32795.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Qt 中的多线程(二)</title><link>http://www.cppblog.com/yuanyajie/archive/2007/08/22/30610.html</link><dc:creator>清源游民</dc:creator><author>清源游民</author><pubDate>Wed, 22 Aug 2007 09:24:00 GMT</pubDate><guid>http://www.cppblog.com/yuanyajie/archive/2007/08/22/30610.html</guid><wfw:comment>http://www.cppblog.com/yuanyajie/comments/30610.html</wfw:comment><comments>http://www.cppblog.com/yuanyajie/archive/2007/08/22/30610.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/yuanyajie/comments/commentRss/30610.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/yuanyajie/services/trackbacks/30610.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;<a href='http://www.cppblog.com/yuanyajie/archive/2007/08/22/30610.html'>阅读全文</a><img src ="http://www.cppblog.com/yuanyajie/aggbug/30610.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/yuanyajie/" target="_blank">清源游民</a> 2007-08-22 17:24 <a href="http://www.cppblog.com/yuanyajie/archive/2007/08/22/30610.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Qt 中的多线程(一)</title><link>http://www.cppblog.com/yuanyajie/archive/2007/08/22/30599.html</link><dc:creator>清源游民</dc:creator><author>清源游民</author><pubDate>Wed, 22 Aug 2007 08:48:00 GMT</pubDate><guid>http://www.cppblog.com/yuanyajie/archive/2007/08/22/30599.html</guid><wfw:comment>http://www.cppblog.com/yuanyajie/comments/30599.html</wfw:comment><comments>http://www.cppblog.com/yuanyajie/archive/2007/08/22/30599.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/yuanyajie/comments/commentRss/30599.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/yuanyajie/services/trackbacks/30599.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;<a href='http://www.cppblog.com/yuanyajie/archive/2007/08/22/30599.html'>阅读全文</a><img src ="http://www.cppblog.com/yuanyajie/aggbug/30599.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/yuanyajie/" target="_blank">清源游民</a> 2007-08-22 16:48 <a href="http://www.cppblog.com/yuanyajie/archive/2007/08/22/30599.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>试用QT中的多语言翻译</title><link>http://www.cppblog.com/yuanyajie/archive/2007/08/03/29258.html</link><dc:creator>清源游民</dc:creator><author>清源游民</author><pubDate>Fri, 03 Aug 2007 02:44:00 GMT</pubDate><guid>http://www.cppblog.com/yuanyajie/archive/2007/08/03/29258.html</guid><wfw:comment>http://www.cppblog.com/yuanyajie/comments/29258.html</wfw:comment><comments>http://www.cppblog.com/yuanyajie/archive/2007/08/03/29258.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/yuanyajie/comments/commentRss/29258.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/yuanyajie/services/trackbacks/29258.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;<a href='http://www.cppblog.com/yuanyajie/archive/2007/08/03/29258.html'>阅读全文</a><img src ="http://www.cppblog.com/yuanyajie/aggbug/29258.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/yuanyajie/" target="_blank">清源游民</a> 2007-08-03 10:44 <a href="http://www.cppblog.com/yuanyajie/archive/2007/08/03/29258.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>空白的七月</title><link>http://www.cppblog.com/yuanyajie/archive/2007/08/01/29112.html</link><dc:creator>清源游民</dc:creator><author>清源游民</author><pubDate>Tue, 31 Jul 2007 16:14:00 GMT</pubDate><guid>http://www.cppblog.com/yuanyajie/archive/2007/08/01/29112.html</guid><wfw:comment>http://www.cppblog.com/yuanyajie/comments/29112.html</wfw:comment><comments>http://www.cppblog.com/yuanyajie/archive/2007/08/01/29112.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/yuanyajie/comments/commentRss/29112.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/yuanyajie/services/trackbacks/29112.html</trackback:ping><description><![CDATA[整个的七月，没有写一篇笔记。所幸的是，学习的脚步没有停止。其间，因为工作上的变故，花了一点时间为考试做了些准备，正好把基础的一些知识复习了一下，所谓温故而知新，收获确实蛮大的。工作的方向有了调整，开始接触不熟悉的东西，扩大一些知识面也不错，谁比谁好也不一定。总之，不管什么情况，只要每天有收获，有进步就心安了。呵，空白的七月，就此交待。 
<img src ="http://www.cppblog.com/yuanyajie/aggbug/29112.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/yuanyajie/" target="_blank">清源游民</a> 2007-08-01 00:14 <a href="http://www.cppblog.com/yuanyajie/archive/2007/08/01/29112.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Qt Model/View 学习笔记 (七) </title><link>http://www.cppblog.com/yuanyajie/archive/2007/06/19/26641.html</link><dc:creator>清源游民</dc:creator><author>清源游民</author><pubDate>Tue, 19 Jun 2007 09:37:00 GMT</pubDate><guid>http://www.cppblog.com/yuanyajie/archive/2007/06/19/26641.html</guid><wfw:comment>http://www.cppblog.com/yuanyajie/comments/26641.html</wfw:comment><comments>http://www.cppblog.com/yuanyajie/archive/2007/06/19/26641.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/yuanyajie/comments/commentRss/26641.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/yuanyajie/services/trackbacks/26641.html</trackback:ping><description><![CDATA[<p>清源游民 <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#103;&#97;&#109;&#101;&#111;&#103;&#114;&#101;&#64;&#103;&#109;&#97;&#105;&#108;&#46;&#99;&#111;&#109;">gameogre@gmail.com</a></p>
<p><span style="FONT-SIZE: 18pt"><em>Delegate&nbsp; 类<br></em></span><br><span style="COLOR: #0000ff"><strong>概念</strong></span></p>
<p>与MVC模式不同，model/view结构没有用于与用户交互的完全独立的组件。一般来讲， view负责把数据展示<br>给用户，也处理用户的输入。为了获得更多的灵性性，交互通过delegagte执行。它既提供输入功能又负责渲染view中的每个数据项。 控制delegates的标准接口在<span style="COLOR: #0000ff">QAbstractItemDelegate</span>类中定义。Delegates通过实现<span style="COLOR: #ff00ff">paint</span>()和<span style="COLOR: #ff00ff">sizeHint</span>()以达到渲染内容的目的。然而，简单的基于widget的delegates,可以从<span style="COLOR: #0000ff">QItemDelegate</span>子类化，而不是<span style="COLOR: #0000ff">QAbstractItemDelegate</span>,这样可以使用它提供的上述函数的缺省实现。delegate可以使用widget来处理编辑过程，也可以直接对事件进行处理。</p>
<p><strong style="COLOR: #0000ff">使用现成的delegate<br></strong>Qt提供的标准views都使用<span style="COLOR: #0000ff">QItemDelegate</span>的实例来提供编辑功能。它以普通的风格来为每个标准view渲染数据项。这些标准的views包括：<span style="COLOR: #0000ff">QListView</span>,<span style="COLOR: #0000ff">QTableView</span>,<span style="COLOR: #0000ff">QTreeView</span>。所有标准的角色都通过标准views包含的缺省delegate进行处理。一个view使用的delegate可以用<span style="COLOR: #ff00ff">itemDelegate</span>()函数取得,而<span style="COLOR: #ff00ff">setItemDelegate</span>()&nbsp;函数可以安装一个定制delegate。</p>
<p><br><strong style="COLOR: #0000ff">一个简单的delegate<br></strong>这个delegate使用<span style="COLOR: #0000ff">QSpinBox</span>来提供编辑功能。它主要想用于显示整数的models上。尽管我们已经建立了一个基于整数的table model,但我们也可以使用<span style="COLOR: #0000ff">QStandardItemModel</span>，因为delegate可以控制数据的录入。我们又建了一个table view来显示model的内容，用我们定制的delegate来编辑。<br><img height=182 alt="" src="http://www.cppblog.com/images/cppblog_com/yuanyajie/2865/o_spinboxdelegate-example.png" width=234 border=0><br>我们从<span style="COLOR: #0000ff">QItemDelegate</span>子类化，这样可以利用它缺省实现的显示功能。当然我们必需提供函数来管理用于编辑的widget:<br>class <span style="COLOR: #0000ff">SpinBoxDelegate</span> : public <span style="COLOR: #0000ff">QItemDelegate</span><br>&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp; Q_OBJECT</p>
<p>&nbsp;public:<br>&nbsp;&nbsp;&nbsp;&nbsp; SpinBoxDelegate(QObject *parent = 0);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: #0000ff">QWidget</span> *<span style="COLOR: #ff00ff">createEditor</span>(<span style="COLOR: #0000ff">QWidget</span> *parent, const <span style="COLOR: #0000ff">QStyleOptionViewItem</span> &amp;option,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; const <span style="COLOR: #0000ff">QModelIndex</span> &amp;index) const;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; void <span style="COLOR: #ff00ff">setEditorData</span>(<span style="COLOR: #0000ff">QWidget</span> *editor, const <span style="COLOR: #0000ff">QModelIndex</span> &amp;index) const;<br>&nbsp;&nbsp;&nbsp;&nbsp; void <span style="COLOR: #ff00ff">setModelData</span>(<span style="COLOR: #0000ff">QWidget</span> *editor, <span style="COLOR: #0000ff">QAbstractItemModel</span> *model,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; const <span style="COLOR: #0000ff">QModelIndex</span> &amp;index) const;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; void <span style="COLOR: #ff00ff">updateEditorGeometry</span>(<span style="COLOR: #0000ff">QWidget</span> *editor,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; const <span style="COLOR: #0000ff">QStyleOptionViewItem</span> &amp;option, const <span style="COLOR: #0000ff">QModelIndex</span> &amp;index) const;<br>&nbsp;};<br>需要注意的是,当一个delegate创建时，不需要安装一个widget，只有在真正需要时才创建这个用于编辑的widget。<br><br><span style="COLOR: #0000ff"><strong>提供编辑器</strong></span><br>在这个例子中，当table view需要提供一个编辑器时，它要求delegate提供一个可用于编辑的widget,它应该适用于当前正被修改的数据项。这正是<span style="COLOR: #ff00ff">createEditor</span>()函数应该实现的：<br>QWidget *SpinBoxDelegate::<span style="COLOR: #ff00ff">createEditor</span>(<span style="COLOR: #0000ff">QWidget</span> *parent,<br>&nbsp;&nbsp;&nbsp;&nbsp; const <span style="COLOR: #0000ff">QStyleOptionViewItem</span> &amp;/* option */,<br>&nbsp;&nbsp;&nbsp;&nbsp; const <span style="COLOR: #0000ff">QModelIndex</span> &amp;/* index */) const<br>&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: #0000ff">QSpinBox</span> *editor = new QSpinBox(parent);<br>&nbsp;&nbsp;&nbsp;&nbsp; editor-&gt;setMinimum(0);<br>&nbsp;&nbsp;&nbsp;&nbsp; editor-&gt;setMaximum(100);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: #ff00ff">return</span> editor;<br>&nbsp;}<br>我们不需要跟踪这个widget的指针，因为view会在不需要时销毁这个widget。我们也给编辑安装了delegate缺省的事件过滤器，这提供了用户期望的标准编辑快捷键。view通过我们定义相应的函数来保证编辑器的数据与几何布局被正确的设置。我们也可以根据不同的model index来创建不同的编辑器，比如，我们有一列整数，一列字符串，我们可以根据哪种列被编辑来创建一个QSpinBox或是QLineEdit。delegate必需提供一个函数把model中的数据拷贝到编辑器中。<br>void SpinBoxDelegate::<span style="COLOR: #ff00ff">setEditorData</span>(<span style="COLOR: #0000ff">QWidget</span> *editor,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; const <span style="COLOR: #0000ff">QModelIndex</span> &amp;index) const<br>&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp; int value = index.model()-&gt;<span style="COLOR: #ff00ff">data</span>(index, Qt::DisplayRole).toInt();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: #0000ff">QSpinBox</span> *spinBox = static_cast&lt;QSpinBox*&gt;(editor);<br>&nbsp;&nbsp;&nbsp;&nbsp; spinBox-&gt;<span style="COLOR: #ff00ff">setValue</span>(value);<br>&nbsp;}<br><br><span style="COLOR: #0000ff"><strong>向model提交数据<br></strong></span>这需要我们实现另外一个函数<span style="COLOR: #ff00ff">setModelData</span>():</p>
<p>void SpinBoxDelegate::<span style="COLOR: #ff00ff">setModelData</span>(<span style="COLOR: #0000ff">QWidget</span> *editor, <span style="COLOR: #0000ff">QAbstractItemModel</span> *model,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; const <span style="COLOR: #0000ff">QModelIndex</span> &amp;index) const<br>&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: #0000ff">QSpinBox</span> *spinBox = static_cast&lt;QSpinBox*&gt;(editor);<br>&nbsp;&nbsp;&nbsp;&nbsp; spinBox-&gt;<span style="COLOR: #ff00ff">interpretText</span>();<br>&nbsp;&nbsp;&nbsp;&nbsp; int value = spinBox-&gt;<span style="COLOR: #ff00ff">value</span>();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; model-&gt;<span style="COLOR: #ff00ff">setData</span>(index, value);<br>&nbsp;}</p>
<p>标准的QItemDelegate类当它完成编辑时会发射closeEditor()信号来通知view。view保证编辑器widget关闭与销毁。本例中我们只提供简单的编辑功能，因此不需要发送个信号。</p>
<p><strong style="COLOR: #0000ff">更新编辑器几何布局</strong></p>
<p>delegate负责管理编辑器的几何布局。这些几何布局信息在编辑创建时或view的尺寸位置发生改变时，<br>都应当被提供。幸运的是，view通过一个view option可以提供这些必要的信息。<br>&nbsp;void <span style="COLOR: #0000ff">SpinBoxDelegate</span>::<span style="COLOR: #ff00ff">updateEditorGeometry</span>(<span style="COLOR: #0000ff">QWidget</span> *editor,<br>&nbsp;&nbsp;&nbsp;&nbsp; const <span style="COLOR: #0000ff">QStyleOptionViewItem</span> &amp;option, const <span style="COLOR: #0000ff">QModelIndex</span> &amp;/* index */) const<br>&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp; editor-&gt;<span style="COLOR: #ff00ff">setGeometry</span>(option.rect);<br>&nbsp;}<br><br><strong style="COLOR: #0000ff">编辑提示</strong><br>编辑完成后，delegate会给别的组件提供有关于编辑处理结果的提示，也提供用于后续编辑操作的一些提示。<br>这可以通过发射带有某种hint的<span style="COLOR: #ff00ff">closeEditor</span>()信号完成。这些信号会被安装在spin box上的缺省的QItemDelegate事件过滤器捕获。对这个缺省的事件过滤来讲，当用户按下回车键，delegate会对model中的数据进行提交，并关闭spin box。<br>我们可以安装自己的事件过滤器以迎合我们的需要，例如，我们可以发射带有Edit<span style="COLOR: #ff00ff">NextItem hint</span>的<br>closeEditor()信号来实现自动开始编辑view中的下一项。</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<img src ="http://www.cppblog.com/yuanyajie/aggbug/26641.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/yuanyajie/" target="_blank">清源游民</a> 2007-06-19 17:37 <a href="http://www.cppblog.com/yuanyajie/archive/2007/06/19/26641.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Qt Model/View 学习笔记 (六) </title><link>http://www.cppblog.com/yuanyajie/archive/2007/06/19/26622.html</link><dc:creator>清源游民</dc:creator><author>清源游民</author><pubDate>Tue, 19 Jun 2007 06:29:00 GMT</pubDate><guid>http://www.cppblog.com/yuanyajie/archive/2007/06/19/26622.html</guid><wfw:comment>http://www.cppblog.com/yuanyajie/comments/26622.html</wfw:comment><comments>http://www.cppblog.com/yuanyajie/archive/2007/06/19/26622.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/yuanyajie/comments/commentRss/26622.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/yuanyajie/services/trackbacks/26622.html</trackback:ping><description><![CDATA[<p>清源游民 <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#103;&#97;&#109;&#101;&#111;&#103;&#114;&#101;&#64;&#103;&#109;&#97;&#105;&#108;&#46;&#99;&#111;&#109;">gameogre@gmail.com</a><br><br><span style="FONT-SIZE: 18pt"><em>在views中选择数据项</em></span></p>
<p><span style="COLOR: #0000ff"><strong>概念</strong></span></p>
<p>用于新的view类中的选择模型比Qt3中的模型有了很大的改进。它为基于model/view架构的选择提供了更为全面的描述。尽管对提供了的views来说，负责操纵选择的标准类已经足以应付，但是你也可以创建特定的选择模型来满足你特殊的需求。<br>关于在view被选择的数据项的信息保持在<span style="COLOR: #0000ff">QItemSelectionModel</span>类的实例中。它也为每个独立的model中的数据项维护model indexes信息，与任何views都关联关系。既然一个model可用于多个views,那么在多个views之间共享选择信息也是可以做到的，这使得多个views可以以一致的方式进行显示。<br>选择由多个选择范围组成。通过仅仅记录开始model indexes与结束model indexes，最大化地记录了可以选择的范围。非连续选择数据项由多个选择范围来描述。选择模型记录model indexes的集合来描述一个选择。最近选择的数据项被称为<span style="COLOR: #0000ff">current</span> <span style="COLOR: #0000ff">selection</span>。应用程序可以通过使用某种类型的选择命令来修改选择的效果。<br>在进行选择操作时，可以把<span style="COLOR: #0000ff">QItemSelectionModel</span>看成是model中所有数据项选择状态的一个记录。一旦建立一个选择模型，所有项的集合都可以选择，撤消选择，或者选择状态进行切换而不需要知道哪个数据项是否已经被选择过。所有被选择的项的indexes在任何时候都可以得到，通过信号槽机制可以通知别的组件发生的变化。<br><br><strong style="COLOR: #0000ff">使用选择模型<br></strong>标准view类提供了缺省的选择模型，它们可以在大次数程序中使用。一个view中的选择模型可以通过调用view的函数<span style="COLOR: #ff00ff">selectionModel</span>()取得，也可以通过<span style="COLOR: #ff00ff">setSelectionModel</span>()在多个views之间共享选择模型，因此总的来说构建一个新的模型一般情况不太必要。<br>通过给<span style="COLOR: #0000ff">QItemSelection</span>指定一个model,一对model indexes，可以创建一个选择。indexes的用法依赖于给定的model,这两个indexes被解释成选择的区块中的左上角项和右下角项。model中的项的选择服从于选择模型。<br><br><span style="COLOR: #0000ff">选择项</span><br>构建一个table model ，它有32个项，用一个table view进行显示：<br>&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: #0000ff">TableModel</span> *model = new TableModel(8, 4, &amp;app);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: #0000ff">QTableView</span> *table = new QTableView(0);<br>&nbsp;&nbsp;&nbsp;&nbsp; table-&gt;<span style="COLOR: #ff00ff">setModel</span>(model);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: #0000ff">QItemSelectionModel</span> *selectionModel = table-&gt;<span style="COLOR: #ff00ff">selectionModel</span>();<br>&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: #0000ff">QModelIndex</span> topLeft;<br>&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: #0000ff">QModelIndex</span> bottomRight;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; topLeft = model-&gt;index(0, 0, QModelIndex());<br>&nbsp;&nbsp;&nbsp;&nbsp; bottomRight = model-&gt;index(5, 2, QModelIndex());<br>&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: #0000ff">QItemSelection</span> selection(topLeft, bottomRight);<br>&nbsp;&nbsp;&nbsp;&nbsp; selectionModel-&gt;<span style="COLOR: #ff00ff">select</span>(selection, QItemSelectionModel::<span style="COLOR: #ff00ff">Select</span>);<br>结果如下：<br><img height=244 alt="" src="http://www.cppblog.com/images/cppblog_com/yuanyajie/2865/o_selected-items-i001.png" width=374 border=0><br><br><span style="COLOR: #0000ff">读取选择状态</span> <br>存储在选择模型中indexes可以用selectionIndexes()函数来读取。它返回一个未排序的model indexes列表，我们可以遍历它，如果我们知道他们关联于哪个model的话。<br>&nbsp;&nbsp;&nbsp; <span style="COLOR: #0000ff">QModelIndexList</span> indexes = selectionModel-&gt;<span style="COLOR: #ff00ff">selectedIndexes</span>();<br>&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: #0000ff">QModelIndex</span> index;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: #ff00ff">foreach</span>(index, indexes) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; QString text = QString("(%1,%2)").arg(index.row()).arg(index.column());<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; model-&gt;setData(index, text);<br>&nbsp;&nbsp;&nbsp;&nbsp; }<br>选择模型在选择发生变化时会发出信号。这用于通知别的组件包括整体与当前焦点项所发生的变化。我们可以连接selectionChanged()信号到一个槽，检查当信号产生时哪些项被选择或被取消选择。这个槽被调用时带有两个参数，它们都是<span style="COLOR: #0000ff">QItemSelection</span>对象，一个包含新被选择的项，另一个包含新近被取消选择的项。下面的代码演示了给新选择的项添加数据内容，新近被取消选择的项的内容被清空。<br>void MainWindow::<span style="COLOR: #ff00ff">updateSelection</span>(const <span style="COLOR: #0000ff">QItemSelection</span> &amp;<span style="COLOR: #ff00ff">selected</span>,<br>&nbsp;&nbsp;&nbsp;&nbsp; const <span style="COLOR: #0000ff">QItemSelection</span> &amp;<span style="COLOR: #ff00ff">deselected</span>)<br>&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: #0000ff">QModelIndex</span> index;<br>&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: #0000ff">QModelIndexList</span> items = selected.<span style="COLOR: #ff00ff">indexes</span>();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: #ff00ff">foreach</span> (index, items) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; QString text = QString("(%1,%2)").arg(index.row()).arg(index.column());<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; model-&gt;setData(index, text);<br>&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; items = deselected.<span style="COLOR: #ff00ff">indexes</span>();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: #ff00ff">foreach</span> (index, items)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; model-&gt;setData(index, "");<br>&nbsp;}<br>也可以通过响应currentChanged()信号来跟踪当前焦点项.对应的槽就有两个接收参数，一个表示之前的焦点，另一个表示当前的焦点。<br>void MainWindow::<span style="COLOR: #ff00ff">changeCurrent</span>(const <span style="COLOR: #0000ff">QModelIndex</span> &amp;current,<br>&nbsp;&nbsp;&nbsp;&nbsp; const <span style="COLOR: #0000ff">QModelIndex</span> &amp;previous)<br>&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp; statusBar()-&gt;showMessage(<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tr("Moved from (%1,%2) to (%3,%4)")<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .arg(previous.row()).arg(previous.column())<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .arg(current.row()).arg(current.column()));<br>&nbsp;}</p>
<p><span style="COLOR: #0000ff">更新选择<br></span>选择指令是通过选择标志提供的，它被定义在QItemSelectionModel::SelectionFlag中。常用的有Select标记，Toggle标记，Deselect标记,Current标记，Clear标记，其意义一目了然。沿上面例子的结果执行以下代码：<br>&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: #0000ff">QItemSelection</span> toggleSelection;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; topLeft = model-&gt;index(2, 1, QModelIndex());<br>&nbsp;&nbsp;&nbsp;&nbsp; bottomRight = model-&gt;index(7, 3, QModelIndex());<br>&nbsp;&nbsp;&nbsp;&nbsp; toggleSelection.<span style="COLOR: #ff00ff">select</span>(topLeft, bottomRight);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; selectionModel-&gt;<span style="COLOR: #ff00ff">select</span>(toggleSelection, QItemSelectionModel::<span style="COLOR: #ff00ff">Toggle</span>);<br>结果如下:<br><img height=244 alt="" src="http://www.cppblog.com/images/cppblog_com/yuanyajie/2865/o_selected-items2-i002.png" width=374 border=0><br><br>缺省情况下，选择指令只针对单个项(由model indexes指定)。然而，选择指令可以通过与另外标记的结合来改变整行和整列。举例来说，假如你只使用一个index来调用select(),但是用Select标记与Rows标记的组合，那么包括那个项的整行都将被选择。看以下示例：<br>&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: #0000ff">QItemSelection</span> columnSelection;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; topLeft = model-&gt;index(0, 1, QModelIndex());<br>&nbsp;&nbsp;&nbsp;&nbsp; bottomRight = model-&gt;index(0, 2, QModelIndex());</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; columnSelection.<span style="COLOR: #ff00ff">select</span>(topLeft, bottomRight);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; selectionModel-&gt;select(columnSelection,<br>&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: #0000ff">QItemSelectionModel</span>::Select | <span style="COLOR: #0000ff">QItemSelectionModel</span>::<span style="COLOR: #ff00ff">Columns</span>);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: #0000ff">QItemSelection</span> rowSelection;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; topLeft = model-&gt;index(0, 0, QModelIndex());<br>&nbsp;&nbsp;&nbsp;&nbsp; bottomRight = model-&gt;index(1, 0, QModelIndex());</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; rowSelection.<span style="COLOR: #ff00ff">select</span>(topLeft, bottomRight);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; selectionModel-&gt;select(rowSelection,<br>&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: #0000ff">QItemSelectionModel</span>::Select | <span style="COLOR: #0000ff">QItemSelectionModel</span>::<span style="COLOR: #ff00ff">Rows</span>);<br>结果如下<br><img height=244 alt="" src="http://www.cppblog.com/images/cppblog_com/yuanyajie/2865/o_selected-items3-i003.png" width=374 border=0><br><br><span style="COLOR: #0000ff">选择模型中所有项<br></span>为了选择model中的所有项，必须先得创建一个选择，它包括当前层次上的所有项:<br>&nbsp;&nbsp;&nbsp; &nbsp;<span style="COLOR: #0000ff">QModelIndex</span> topLeft = model-&gt;index(0, 0, parent);<br>&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: #0000ff">QModelIndex</span> bottomRight = model-&gt;<span style="COLOR: #ff00ff">index</span>(model-&gt;<span style="COLOR: #ff00ff">rowCount</span>(parent)-1,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; model-&gt;<span style="COLOR: #ff00ff">columnCount</span>(parent)-1, parent);<br><br>&nbsp;&nbsp;&nbsp; <span style="COLOR: #0000ff">QItemSelection</span> selection(topLeft, bottomRight);<br>&nbsp;&nbsp;&nbsp;&nbsp; selectionModel-&gt;<span style="COLOR: #ff00ff">select</span>(selection, QItemSelectionModel::Select);<br>顶级index可以这样：<br>QModelIndex parent = <span style="COLOR: #ff00ff">QModelIndex</span>();<br>对具有层次结构的model来说，可以使用<span style="COLOR: #ff00ff">hasChildren</span>()函数来决定给定项是否是其它项的父项。<br></p>
<img src ="http://www.cppblog.com/yuanyajie/aggbug/26622.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/yuanyajie/" target="_blank">清源游民</a> 2007-06-19 14:29 <a href="http://www.cppblog.com/yuanyajie/archive/2007/06/19/26622.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Qt Model/View 学习笔记 (五) </title><link>http://www.cppblog.com/yuanyajie/archive/2007/06/18/26568.html</link><dc:creator>清源游民</dc:creator><author>清源游民</author><pubDate>Mon, 18 Jun 2007 08:15:00 GMT</pubDate><guid>http://www.cppblog.com/yuanyajie/archive/2007/06/18/26568.html</guid><wfw:comment>http://www.cppblog.com/yuanyajie/comments/26568.html</wfw:comment><comments>http://www.cppblog.com/yuanyajie/archive/2007/06/18/26568.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/yuanyajie/comments/commentRss/26568.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/yuanyajie/services/trackbacks/26568.html</trackback:ping><description><![CDATA[<p>清源游民 gameogre@gmail.com<br><br><span style="FONT-SIZE: 18pt"><em>View 类<br></em></span><br><span style="COLOR: #0000ff"><strong>概念</strong></span></p>
<p>在model/view架构中，view从model中获得数据项然后显示给用户。数据显示的方式不必与model提供的表示方式相同，可以与底层存储数据项的数据结构完全不同。<br>内容与显式的分离是通过由<span style="COLOR: #0000ff">QAbstractItemModel</span>提供的标准模型接口，由<span style="COLOR: #0000ff">QAsbstractItemview</span>提供的标准视图接口共同实现的。普遍使用model index来表示数据项。view负责管理从model中读取的数据的外观布局。<br>它们自己可以去渲染每个数据项，也可以利用delegate来既处理渲染又进行编辑。<br>除了显示数据，views也处理数据项的导航，参与有关于数据项选择的部分功能。view也实现一些基本的用户接口特性，如上下文菜单与拖拽功能。view也为数据项提供了缺省的编程功能，也可搭配delegate实现更为特殊的定制编辑的需求。<br>一个view创建时必不需要model,但在它能显示一些真正有用的信息之前，必须提供一个model。view通过使用<br><strong style="COLOR: #993366">selections</strong>来跟踪用户选择的数据项。每个view可以维护单独使用的selections，也可以在多个views之间共享。有些views,如<span style="COLOR: #0000ff">QTableView</span>和<span style="COLOR: #0000ff">QTreeView</span>,除数据项之外也可显示标题(Headers)，标题部分通过一个view来实现，QHeaderView。标题与view一样总是从相同的model中获取数据。从 model中获取数据的函数是<span style="COLOR: #0000ff">QabstractItemModel</span>::<span style="COLOR: #800080"><strong>headerDate</strong></span>()，一般总是以表单的形式中显示标题信息。可以从<span style="COLOR: #0000ff">QHeaderView</span>子类化，以实现更为复杂的定制化需求。<br><br><span style="COLOR: #0000ff"><strong>使用现成的view<br></strong></span>Qt提供了三个现成的view 类，它们能够以用户熟悉的方式显示model中的数据。<span style="COLOR: #0000ff">QListView</span>把model中的数据项以一个简单的列表的形式显示，或是以经典的图标视图的形式显示。<span style="COLOR: #0000ff">QTreeView</span>把model中的数据项作为具有层次结构的列表的形式显示，它允许以紧凑的深度嵌套的结构进行显示。<span style="COLOR: #0000ff">QTableView</span>却是把model中的数据项以表格的形式展现，更像是一个电子表格应用程序的外观布局。<br><img style="WIDTH: 465px; HEIGHT: 212px" height=212 alt="" src="http://www.cppblog.com/images/cppblog_com/yuanyajie/2865/r_standard-views001.png" width=465 border=0><br>以上这些标准view的行为足以应付大多数的应用程序，它们也提供了一些基本的编辑功能，也可以定制特殊的需求。</p>
<p><span style="COLOR: #0000ff"><strong>使用model</strong></span><br>以前的例子中创建过一个string list model,可以给它设置一些数据，再创建一个view把model中的内容展示出来：<br>int main(int argc, char *argv[])<br>&nbsp;{<br>&nbsp;&nbsp;&nbsp;<span style="COLOR: #0000ff">QApplication</span> app(argc, argv);</p>
<p>&nbsp;<span style="COLOR: #008000">// Unindented for quoting purposes:<br></span>&nbsp;<span style="COLOR: #0000ff">QStringList</span> numbers;<br>&nbsp;numbers &lt;&lt; "One" &lt;&lt; "Two" &lt;&lt; "Three" &lt;&lt; "Four" &lt;&lt; "Five";</p>
<p>&nbsp;<span style="COLOR: #0000ff">QAbstractItemModel</span> *model = new <span style="COLOR: #0000ff">StringListModel</span>(numbers);<br>&nbsp;<span style="COLOR: #008000">//要注意的是，这里把StringListModel作为一个QAbstractItemModel来使用。这样我们就可以<br>&nbsp;//使用model中的抽象接口，而且如果将来我们用别的model代替了当前这个model,这些代码也会照样工作。<br>&nbsp;//QListView提供的列表视图足以满足当前这个model的需要了。<br></span>&nbsp;<span style="COLOR: #0000ff">QListView</span> *view = new QListView;<br>&nbsp;view-&gt;<span style="COLOR: #800080"><strong>setModel</strong></span>(model);<br>&nbsp; view-&gt;<span style="COLOR: #800080"><strong>show</strong></span>();<br>&nbsp; return app.exec();<br>}<br><img height=218 alt="" src="http://www.cppblog.com/images/cppblog_com/yuanyajie/2865/r_stringlistmodel.png" width=264 border=0><br>view会渲染model中的内容，通过model的接口来访问它的数据。当用户试图编辑数据项时，view会使用缺省的delegate来提供一个编辑构件。<br><span style="COLOR: #0000ff"><strong>一个model,多个views</strong></span><br>为多个views提供相同的model是非常简单的事情，只要为每个view设置相同的model。<br>&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: #0000ff">QTableView</span> *firstTableView = new QTableView;<br>&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: #0000ff">QTableView</span> *secondTableView = new QTableView;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; firstTableView-&gt;<span style="COLOR: #800080"><strong>setModel</strong></span>(model);<br>&nbsp;&nbsp;&nbsp;&nbsp; secondTableView-&gt;<span style="COLOR: #800080"><strong>setModel</strong></span>(model);<br>在model/view架构中信号、槽机制的使用意味着model中发生的改变会传递中联结的所有view中，这保证了<br>不管我们使用哪个view，访问的都是同样的一份数据。<br><img height=232 alt="" src="http://www.cppblog.com/images/cppblog_com/yuanyajie/2865/r_sharedmodel-tableviews.png" width=573 border=0><br>上面的图展示了一个model上的两个不同的views,尽管在不同的view中显示的model中的数据是一致的，每个<br>view都维护它们自己的内部选择模型，但有时候在某些情况下，共享一个选择模型也是合理的。</p>
<p><strong style="COLOR: #0000ff">处理数据项的选择<br></strong>view中数据项选择机制由<span style="COLOR: #0000ff">QItemSelectionModel</span>类提供。所有标准的view缺省都构建它们自己的选择模型，<br>以标准的方式与它们交互。选择模型可以用<strong style="COLOR: #800080">selectionModel</strong>()函数取得，替代的选择模型也可以通过<br><span style="COLOR: #800080"><strong>setSelectionModel</strong></span>()来设置。当我们想在一个model上提供多个一致的views时，这种对选择模型的控制能力非常有用。通常来讲，除非你子类化一个model或view,你不必直接操纵selections的内容。<br><br><span style="COLOR: #0000ff"><strong>多个views之间共享选择</strong></span><br>接着上边的例子，我们可以这样：<br>secondTableView-&gt;<span style="COLOR: #800080"><strong>setSelectionModel</strong></span>(firstTableView-&gt;<span style="COLOR: #800080"><strong>selectionModel</strong></span>());<br>现在所有views都在同样的选择模型上操作，数据与选择项都保持同步。<br><img height=232 alt="" src="http://www.cppblog.com/images/cppblog_com/yuanyajie/2865/r_sharedselection-tableviews.png" width=572 border=0><br>上面的例子中，两个view的类型是相同的，假如这两个view类型不同，那么所选择的数据项在每个view<br>中的表现形式会有很大的不同。例如，在一个table view中一个连续的选择，在一个tree view中表现出<br>来的可能会是几个高亮的数据项片断的组合。</p>
<img src ="http://www.cppblog.com/yuanyajie/aggbug/26568.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/yuanyajie/" target="_blank">清源游民</a> 2007-06-18 16:15 <a href="http://www.cppblog.com/yuanyajie/archive/2007/06/18/26568.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Qt Model/View 学习笔记 (四) </title><link>http://www.cppblog.com/yuanyajie/archive/2007/06/18/26555.html</link><dc:creator>清源游民</dc:creator><author>清源游民</author><pubDate>Mon, 18 Jun 2007 03:56:00 GMT</pubDate><guid>http://www.cppblog.com/yuanyajie/archive/2007/06/18/26555.html</guid><wfw:comment>http://www.cppblog.com/yuanyajie/comments/26555.html</wfw:comment><comments>http://www.cppblog.com/yuanyajie/archive/2007/06/18/26555.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/yuanyajie/comments/commentRss/26555.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/yuanyajie/services/trackbacks/26555.html</trackback:ping><description><![CDATA[<p>清源游民 <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#103;&#97;&#109;&#101;&#111;&#103;&#114;&#101;&#64;&#103;&#109;&#97;&#105;&#108;&#46;&#99;&#111;&#109;">gameogre@gmail.com</a><br><br><span style="FONT-SIZE: 18pt">创建新的Models<br><br></span><strong><span style="COLOR: #0000ff">介绍</span><br></strong>model/view组件之间功能的分离，允许创建model利用现成的views。这也可以使用标准的功能 图形用户接口组件像QListView,QTableView和QTreeView来显示来自各种数据源的数据为。<br>QAbstractListModel类提供了非常灵活的接口，允许数据源以层次结构的形式来管理信息，也允许以某种<br>方式对数据进行插入、删除、修改和存储。它也提供了对拖拽操作的支持。<br><span style="COLOR: #0000ff">QAbstractListModel</span>与<span style="COLOR: #0000ff">QAbstractTableModel</span>为简单的非层次结构的数据提供了接口，对于比较简单的list和table models来说，这是不错的一个开始点。<br><br><span style="COLOR: #0000ff"><strong>设计一个Model<br></strong></span>当我们为存在的数据结构新建一个model时，首先要考虑的问题是应该选用哪种model来为这些数据提供接口。<br>假如数据结构可以用数据项的列表或表来表示，那么可以考虑子类化<span style="COLOR: #0000ff">QAbstractListModel</span>或<span style="COLOR: #0000ff">QAbstractTableModel</span><br>,既然这些类已经合理地对许多功能提供缺省实现。<br>然而，假如底层的数据结构只能表示成具有层次结构的树型结构，那么必须得子类化<span style="COLOR: #0000ff">QAbstractItemModel</span>。<br>无论底层的数据结构采取何种形式，在特定的model中实现标准的<span style="COLOR: #0000ff">QAbstractItemModel</span> API总是一个不错的主意，这使得可以使用更自然的方式对底层的数据结构进行访问。这也使得用数据构建model 更为容易，其他<br>的model/view组件也可以使用标准的API与之进行交互。<br><br><span style="COLOR: #0000ff"><strong>一个只读model示例</strong><br></span>这个示例实现了一个简单的，非层次结构的，只读的数据model,它基于<span style="COLOR: #0000ff">QStringistModel</span>类。它有一个<span style="COLOR: #0000ff">QStringList</span>作为它内部的数据源，只实现了一些必要的接口。为了简单化，它子类化了<span style="COLOR: #0000ff">QAbstractListModel</span>,这个基类提供了合理的缺省行为，对外提供了比<span style="COLOR: #0000ff">QAbstractItemModel</span>更为简单的接口。当我们实现一个model时，不要忘了<span style="COLOR: #0000ff">QAbstractItemModel</span>本身不存储任何数据，它仅仅提供了给views访问<br>数据的接口。<br>class <span style="COLOR: #0000ff">StringListModel</span> : public <span style="COLOR: #0000ff">QAbstractListModel</span><br>&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp; Q_OBJECT</p>
<p>&nbsp;public:<br>&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: #0000ff">StringListModel</span>(const QStringList &amp;strings, QObject *parent = 0)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : <span style="COLOR: #0000ff">QAbstractListModel</span>(parent), stringList(strings) {}</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; int <span style="COLOR: #ff00ff">rowCount</span>(const QModelIndex &amp;parent = QModelIndex()) const;<br>&nbsp;&nbsp;&nbsp;&nbsp; QVariant <span style="COLOR: #ff00ff">data</span>(const QModelIndex &amp;index, int role) const;<br>&nbsp;&nbsp;&nbsp;&nbsp; QVariant <span style="COLOR: #ff00ff">headerData</span>(int section, Qt::Orientation orientation,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int role = Qt::DisplayRole) const;</p>
<p>&nbsp;private:<br>&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: #0000ff">QStringList</span> stringList;<br>&nbsp;};<br>除了构造函数，我们仅需要实现两个函数：<span style="COLOR: #ff00ff">rowCount</span>()返回model中的行数，<span style="COLOR: #ff00ff">data</span>()返回与特定model index对应的数据项。具有良好行为的model也会实现<span style="COLOR: #ff00ff">headerData</span>()，它返回tree和table views需要的，在标题中显示的数据。<br>因为这是一个非层次结构的model,我们不必考虑父子关系。假如model具有层次结构，我们也应该实现<span style="COLOR: #ff00ff">index</span>()与<span style="COLOR: #ff00ff">parent</span>()函数。<br><br><strong style="COLOR: #0000ff">Model的尺寸</strong><br>我们认为model中的行数与string list中的string数目一致：<br>int <span style="COLOR: #3366ff">StringListModel</span>::<span style="COLOR: #ff00ff">rowCount</span>(const QModelIndex &amp;parent) const<br>&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp; return stringList.count();<br>&nbsp;}<br>在缺省情况下，从<span style="COLOR: #0000ff">QAbstractListModel</span>派生的model只具有一列，因此不需要实现columnCount()。<br><br><span style="COLOR: #0000ff"><strong>Model 标题与数据</strong></span><br>&nbsp;QVariant <span style="COLOR: #0000ff">StringListModel</span>::<span style="COLOR: #ff00ff">data</span>(const QModelIndex &amp;index, int role) const<br>&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp; if (!index.isValid())<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return QVariant();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; if (index.row() &gt;= stringList.size())<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return QVariant();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; if (role == Qt::DisplayRole)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return stringList.at(index.row());<br>&nbsp;&nbsp;&nbsp;&nbsp; else<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return QVariant();<br>&nbsp;}<br>QVariant <span style="COLOR: #0000ff">StringListModel</span>::<span style="COLOR: #ff00ff">headerData</span>(int section, Qt::Orientation orientation,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int role) const<br>&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp; if (role != Qt::DisplayRole)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return QVariant();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; if (orientation == Qt::Horizontal)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return QString("Column %1").arg(section);<br>&nbsp;&nbsp;&nbsp;&nbsp; else<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return QString("Row %1").arg(section);<br>&nbsp;}<br>一个数据项可能有多个角色，根据角色的不同输出不同的数据。上例中，model中的数据项只有一个角色 ，<br>DisplayRole,然而我们也可以重用提供给DisplayRole的数据，作为别的角色使用，如我们可以作为ToolTipRole来用。<br><br><span style="COLOR: #0000ff"><strong>可编辑的model<br></strong></span>上面我们演示了一个只读的model,它只用于向用户显示，对于许多程序来说，可编辑的list model可能更有用。我们只需要给只读的model提供另外两个函数flags()与setData()的实现。下列函数声明被添加到类定义中：<br>&nbsp;&nbsp;&nbsp;&nbsp; Qt::<span style="COLOR: #0000ff">ItemFlags</span> <span style="COLOR: #ff00ff">flags</span>(const QModelIndex &amp;index) const;<br>&nbsp;&nbsp;&nbsp;&nbsp; bool <span style="COLOR: #ff00ff">setData</span>(const QModelIndex &amp;index, const QVariant &amp;value,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int role = Qt::EditRole);<br><br><span style="COLOR: #0000ff">让model可编辑<br></span>delegate会在创建编辑器之前检查数据项是否是可编辑的。model必须得让delegate知道它的数据项是可<br>编辑的。这可以通过为每一个数据项返回一个正确的标记得到，在本例中，我们假设所有的数据项都是<br>可编辑可选择的：<br>Qt::<span style="COLOR: #0000ff">ItemFlags</span> <span style="COLOR: #0000ff">StringListModel</span>::<span style="COLOR: #ff00ff">flags</span>(const QModelIndex &amp;index) const<br>&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp; if (!index.isValid())<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return Qt::ItemIsEnabled;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; return <span style="COLOR: #0000ff">QAbstractItemModel</span>::flags(index) | Qt::ItemIsEditable;<br>&nbsp;}<br>我们不必知道delegate执行怎样实际的编辑处理过程，我们只需提供给delegate一个方法，delegate会使用它对model中的数据进行设置。这个特殊的函数就是setData():<br>bool <span style="COLOR: #0000ff">StringListModel</span>::<span style="COLOR: #ff00ff">setData</span>(const QModelIndex &amp;index,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; const QVariant &amp;value, int role)<br>&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp; if (index.isValid() &amp;&amp; role == Qt::EditRole) {</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stringList.replace(index.row(), value.toString());<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: #ff00ff">emit</span> <span style="COLOR: #ff00ff">dataChanged</span>(index, index);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return true;<br>&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp; return false;<br>&nbsp;}<br>当数据被设置后，model必须得让views知道一些数据发生了变化，这可通过发射一个dataChanged() 信号实现。<br>因为只有一个数据项发生了变化，因此在信号中说明的变化范围只限于一个model index。<br><span style="COLOR: #0000ff">插入，删除行<br></span>在model中改变行数与列数是可能的。当然在本列中，只考虑行的情况，我们只需要重新实现插入、删除<br>的函数就可以了，下面应在类定义中声明：<br>&nbsp;&nbsp;&nbsp;&nbsp; bool <span style="COLOR: #ff00ff">insertRows</span>(int position, int rows, const QModelIndex &amp;index = QModelIndex());<br>&nbsp;&nbsp;&nbsp;&nbsp; bool <span style="COLOR: #ff00ff">removeRows</span>(int position, int rows, const QModelIndex &amp;index = QModelIndex());<br>既然model中的每行对应于列表中的一个string,因此，insertRows()函数在string list&nbsp; 中指定位置插入一个空string,<br>父index通常用于决定model中行列的位置，本例中只有一个单独的顶级项，困此只需要在list中插入空string。<br>bool <span style="COLOR: #0000ff">StringListModel</span>::insertRows(int position, int rows, const QModelIndex &amp;parent)<br>&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: #ff00ff">beginInsertRows</span>(QModelIndex(), position, position+rows-1);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; for (int row = 0; row &lt; rows; ++row) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stringList.insert(position, "");<br>&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: #ff00ff">endInsertRows</span>();<br>&nbsp;&nbsp;&nbsp;&nbsp; return true;<br>&nbsp;}<br>beginInsertRows()通知其他组件行数将会改变。endInsertRows()对操作进行确认与通知。<br>返回true表示成功。<br>删除操作与插入操作类似：<br>bool <span style="COLOR: #0000ff">StringListModel</span>::removeRows(int position, int rows, const QModelIndex &amp;parent)<br>&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: #ff00ff">beginRemoveRows</span>(QModelIndex(), position, position+rows-1);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; for (int row = 0; row &lt; rows; ++row) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stringList.removeAt(position);<br>&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: #ff00ff">endRemoveRows</span>();<br>&nbsp;&nbsp;&nbsp;&nbsp; return true;<br>&nbsp;}</p>
<img src ="http://www.cppblog.com/yuanyajie/aggbug/26555.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/yuanyajie/" target="_blank">清源游民</a> 2007-06-18 11:56 <a href="http://www.cppblog.com/yuanyajie/archive/2007/06/18/26555.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Qt Model/View 学习笔记 (三) </title><link>http://www.cppblog.com/yuanyajie/archive/2007/06/17/26488.html</link><dc:creator>清源游民</dc:creator><author>清源游民</author><pubDate>Sun, 17 Jun 2007 06:31:00 GMT</pubDate><guid>http://www.cppblog.com/yuanyajie/archive/2007/06/17/26488.html</guid><wfw:comment>http://www.cppblog.com/yuanyajie/comments/26488.html</wfw:comment><comments>http://www.cppblog.com/yuanyajie/archive/2007/06/17/26488.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/yuanyajie/comments/commentRss/26488.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/yuanyajie/services/trackbacks/26488.html</trackback:ping><description><![CDATA[<p>清源游民 <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#103;&#97;&#109;&#101;&#111;&#103;&#114;&#101;&#64;&#103;&#109;&#97;&#105;&#108;&#46;&#99;&#111;&#109;"><u><font color=#000000>gameogre@gmail.com</font></u></a><br><br><span style="FONT-SIZE: 24pt"><em>Model类<br></em></span><br><span style="COLOR: #0000ff"><strong>基本概念</strong><br></span>在model/view构架中，model为view和delegates使用数据提供了标准接口。在Qt中，标准接口<span style="COLOR: #0000ff">QAbstractItemModel</span>类中被定义。不管数据在底层以何种数据结构存储，<span style="COLOR: #0000ff">QAabstractItemModel</span>的子类会以层次结构的形式来表示数据，结构中包含了数据项表。我们按这种约定来访问model中的数据项，但这个约定不会对如何显示这些数据有任何限制。数据发生改变时，model通过信号槽机制来通知关联的views。<br><img height=332 alt="" src="http://www.cppblog.com/images/cppblog_com/yuanyajie/2865/o_modelview-models1.png" width=618 border=0></p>
<p><span style="COLOR: #0000ff"><strong>Model Indexes</strong></span></p>
<p>为了使数据存储与数据访问分开，引入了model index的概念。通过model index，可以引用model中的数据项，Views和delegates都使用indexes来访问数据项，然后再显示出来。因此，只有model需要了解如何获取数据，被model管理的数据类型可以非常广泛地被定义。Model indexes包含一个指向创建它们的model的指针，这会在配合多个model工作时避免混乱。<br><span style="COLOR: #0000ff">QAbstractItemModel</span> *model = index.<span style="COLOR: #ff00ff">model</span>();</p>
<p>model indexes提供了对一项数据信息的临时引用，通过它可以访问或是修改model中的数据。既然model有时会重新组织内部的数据结构，这时model indexes便会失效，因此不应该保存临时的model indexes。假如需要一个对数据信息的长期的引用，那么应该创建一个<span style="COLOR: #0000ff">persistent</span> model index。这个引用会保持更新。临时的model indexes由<span style="COLOR: #0000ff">QModelIndex</span>提供，而具有持久能力的model indexes则由<span style="COLOR: #0000ff">QPersistentModelIndex</span>提供。在获取对应一个数据项的model index时，需要考虑有关于model的三个属性：行数，列数，父项的model index。</p>
<p><br><span style="COLOR: #0000ff"><strong>行与列</strong></span><br>在最基本的形式中，一个model可作为一个简单的表来访问，每个数据项由行，列数来定位。这必不意味着<br>底层的数据用数组结构来存储。行和列的使用仅仅是一种约定，它允许组件之间相互通讯。可以通过指定<br>model中的行列数来获取任一项数据，可以得到与数据项一一对应的那个index。<br><span style="COLOR: #0000ff">QModelIndex</span> index = model-&gt;<span style="COLOR: #ff00ff">index</span>(row, column, ...);<br>Model为简单的，单级的数据结构如list与tables提供了接口，它们如上面代码所显示的那样，不再需要别的信息被提供。当我们在获取一个model index时，我们需要提供另外的信息。<br><img height=303 alt="" src="http://www.cppblog.com/images/cppblog_com/yuanyajie/2865/r_modelview-tablemodel.png" width=245 border=0></p>
<p>上图代表一个基本的table model，它的每一项用一对行列数来定位。通过行列数，可以获取代表一个数据项的model index . <br><span style="COLOR: #0000ff">QModelIndex</span> indexA = model-&gt;<span style="COLOR: #ff00ff">index</span>(0, 0, <span style="COLOR: #ff00ff">QModelIndex</span>());<br>&nbsp;<span style="COLOR: #0000ff">QModelIndex</span> indexB = model-&gt;<span style="COLOR: #ff00ff">index</span>(1, 1, <span style="COLOR: #ff00ff">QModelIndex</span>());<br>&nbsp;<span style="COLOR: #0000ff">QModelIndex</span> indexC = model-&gt;<span style="COLOR: #ff00ff">index</span>(2, 1, <span style="COLOR: #ff00ff">QModelIndex</span>());<br>一个model的顶级项,由QModelIndex()取得，它们上式被用作父项。</p>
<p><span style="COLOR: #0000ff"><strong>父项</strong></span><br>类似于表的接口在搭配使用table或list view时理想的，这种行列系统与view显示的方式是确切匹配的。<br>然则，像tree views这种结构需要model提供更为灵活的接口来访问数据项。每个数据项可能是别的项的<br>父项，上级的项可以获取下级项的列表。<br>当获取model中数据项的index时，我们必须指定关于数据项的父项的信息。在model外部，引用一个数据<br>项的唯一方法就是通过model index,因此需要在求取model index时指定父项的信息。<br><span style="COLOR: #0000ff">QModelIndex</span> index = model-&gt;<span style="COLOR: #ff00ff">index</span>(row, column, parent);<br><img height=332 alt="" src="http://www.cppblog.com/images/cppblog_com/yuanyajie/2865/o_modelview-treemodel.png" width=251 border=0><br>上图中，A项和C项作为model中顶层的兄弟项：<br>&nbsp;<span style="COLOR: #0000ff">QModelIndex</span> indexA = model-&gt;<span style="COLOR: #ff00ff">index</span>(0, 0, QModelIndex());<br>&nbsp;<span style="COLOR: #0000ff">QModelIndex</span> indexC = model-&gt;<span style="COLOR: #ff00ff">index</span>(2, 1, QModelIndex());<br>A有许多孩子，它的一个孩子B用以下代码获取：<br><span style="COLOR: #0000ff">QModelIndex</span> indexB = model-&gt;<span style="COLOR: #ff00ff">index</span>(1, 0, indexA);<br><br><strong><span style="COLOR: #0000ff">项角色</span><br></strong>model中的项可以作为各种角色来使用，这允许为不同的环境提供不同的数据。举例来说，Qt::DisplayRole被用于访问一个字符串，它作为文本会在view中显示。典型地，每个数据项都可以为许多不同的角色提供数据，标准的角色在Qt::ItemDataRole中定义。我们可以通过指定model index与角色来获取我们需要的数据：<br><span style="COLOR: #0000ff">QVariant</span> value = model-&gt;<span style="COLOR: #ff00ff">data</span>(index, role);<br><img height=265 alt="" src="http://www.cppblog.com/images/cppblog_com/yuanyajie/2865/o_modelview-roles.png" width=379 border=0></p>
<p>角色指出了从model中引用哪种类型的数据。views可以用不同的形式显示角色，因此为每个角色提供正确<br>的信息是非常重要的。通过为每个角色提供适当数据，model也为views和delegates提供了暗示，如何正确地<br>把这些数据项显给用户。不同的views可以自由地解析或忽略这些数据信息，对于特殊的场合，也可以定义<br>一些附加的角色。<br><span style="COLOR: #0000ff"><strong>概念总结：</strong></span><br>1，Model indexes为views与delegages提供model中数据项定位的信息，它与底层的数据结构无关。<br>2，通过指定行，列数，父项的model index来引用数据项。<br>3,依照别的组件的要求，model indexes被model构建。<br>4，使用index()时，如果指定了有效的父项的model index,那么返回得到的model index对应于父项的某个孩子。<br>5，使用index()时，如果指定了无效的父项的model index,那么返回得到的model index对应于顶层项的某个孩子。<br>6, 角色对一个数据项包含的不同类型的数据给出了区分。</p>
<p><span style="COLOR: #0000ff"><strong>使用Model Indexes</strong></span><br><span style="COLOR: #0000ff">QDirModel</span> *model = new <span style="COLOR: #0000ff">QDirModel</span>;<br>&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: #0000ff">QModelIndex</span> parentIndex = model-&gt;<span style="COLOR: #ff00ff">index</span>(QDir::currentPath());<br>&nbsp;&nbsp;&nbsp;&nbsp; int numRows = model-&gt;<span style="COLOR: #ff00ff">rowCount</span>(parentIndex);<br>&nbsp;for (int row = 0; row &lt; numRows; ++row)<br>&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: #0000ff">QModelIndex</span> index = model-&gt;<span style="COLOR: #ff00ff">index</span>(row, 0, parentIndex);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tring text = model-&gt;<span style="COLOR: #ff00ff">data</span>(index, Qt::DisplayRole).toString();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: #993366">&nbsp;&nbsp; // Display the text in a widget.</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; }<br>以上的例子说明了从model中获取数据的基本原则：<br>1，model的尺寸可以从<span style="COLOR: #ff00ff">rowCount</span>()与<span style="COLOR: #ff00ff">columnCount</span>()中得出。这些函数通常都需要一个表示父项的model index。<br>2，model indexes用来从model中访问数据项，数据项用行，列，父项model index定位。<br>3, 为了访问model顶层项，可以使用<span style="COLOR: #ff00ff">QModelIndex</span>()指定。<br>4, 数据项为不同的角色提供不同的数据。为了获取数据，除了model index之外，还要指定角色。<br></p>
<img src ="http://www.cppblog.com/yuanyajie/aggbug/26488.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/yuanyajie/" target="_blank">清源游民</a> 2007-06-17 14:31 <a href="http://www.cppblog.com/yuanyajie/archive/2007/06/17/26488.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>