64 Star 180 Fork 34

qtguide / qtguide

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
ch08-01.htm 254.40 KB
一键复制 编辑 原始数据 按行查看 历史
qtguide 提交于 2016-11-03 21:31 . update ch2.2 with c++11
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810
<!DOCTYPE html>
<html>
<head>
<meta content="text/html; charset=UTF-8" http-equiv="content-type">
<title>ch08-01</title>
<link href="css/style.css" rel="stylesheet" type="text/css">
<link rel="stylesheet" href="thumbnailviewer.css" type="text/css">
<script src="thumbnailviewer.js" type="text/javascript">
/***********************************************
* Image Thumbnail Viewer Script- © Dynamic Drive (www.dynamicdrive.com)
* This notice must stay intact for legal use.
* Visit http://www.dynamicdrive.com/ for full source code
***********************************************/
</script> </head>
<body>
<div class="os1">8.1 列表控件</div>
<br>
之前第 7 章有多个示例都用到了列表控件,本节再详细介绍一下列表控件 QListWidget 和它的数据条目
QListWidgetItem,列表控件用于显示单列多行数据,而且可以用程序代码编写能够手动编辑的动态列表,列表的条目可以有图标,并有多种显示模式,本节会通过两
个示例学习列表控件丰富的功能。<br>
<br>
<div class="os2">8.1.1 QListWidget</div>
<br>
在 Qt 设计师,左边的控件工具箱可以看到本章三个基于条目控件:<br>
<center> <img src="images/ch08/ch08-01-01.png" alt="item-based widgets" width="800">
</center>
QListWidget 的基类是 QListView 视图类,关于基类的内容本节不介绍,等到模型视图章节再讲,本节只关注 QListWidget
本身的函数。<br>
QListWidget 的构造函数很简单:<br>
<div class="code">QListWidget(QWidget * parent = 0)</div>
parent 是父窗口指针,如果用设计师拖控件,一般也不用手动调用构造函数。QListWidget
主要的函数是围绕条目添加、删除、选中条目、显示模式等功能以及相关的信号和槽,下面大致对这些功能函数分类来讲解:<br>
(1)添加条目的函数<br>
<div class="code">void QListWidget::​addItem(QListWidgetItem * item)</div>
这个添加函数需要实现 new 一个 QListWidgetItem 条目对象,然后添加到列表控件末尾,下面小节会专门讲 QListWidgetItem
类。<br>
<div class="code">void QListWidget::​addItem(const QString &amp; label)</div>
这第二个添加函数其实更常用,因为更简便,功能是将字符串 label 添加到列表控件末尾显示,其实该函数内部会自动根据字符串 new
一个条目对象添加到列表控件。<br>
如果有设置好的字符串列表,那么可以通过如下函数把多个字符串全部添加到列表控件:<br>
<div class="code">void QListWidget::​addItems(const QStringList &amp;
labels)</div>
<br>
add* 函数是将条目添加到末尾,如果要将条目插入到指定行 row 位置,则使用 insert* 函数:<br>
<div class="code">void QListWidget::​insertItem(int row, QListWidgetItem *
item) //插入条目到第 row 行</div>
<div class="code">void QListWidget::​insertItem(int row, const QString &amp;
label) //插入字符串到第 row 行</div>
<div class="code">void QListWidget::​insertItems(int row, const QStringList
&amp; labels) //插入多个字符串到从 row 行开始的多个行</div>
<br>
获取列表控件里面的条目计数使用如下函数:<br>
<div class="code">int QListWidget::count() const</div>
<br>
(2)删除函数<br>
因为是基于条目的控件,所以列表控件的删除单个条目函数名字是 takeItem():<br>
<div class="code">QListWidgetItem * QListWidget::​takeItem(int row)</div>
takeItem() 根据行号从列表控件移除一个条目,并返回该条目指针,如果行号不合法,返回 NULL 指针。<br>
如果返回的是实际存在的条目,那么需要注意,返回的条目指针需要手动 delete 掉,因为列表控件不再拥有该条目,该条目不会由列表控件析构时自动删除。<br>
​takeItem() 函数还有第二个用途,因为列表控件没有直接的调整条目前后顺序的函数,可以先将要调整顺序的条目移出来
​takeItem(),然后再调用 ​insertItem() 把这个条目插入到新的位置。<br>
<br>
如果要清空整个列表控件,删除之前添加的所有条目,可以调用槽函数:<br>
<div class="code">void QListWidget::​clear()</div>
<br>
(3)条目访问函数<br>
根据行号获取条目对象的指针,使用如下函数:<br>
<div class="code">QListWidgetItem * QListWidget::​item(int row) const</div>
如果已知列表控件含有的条目对象指针,反查当前行号,使用如下函数:<br>
<div class="code">int QListWidget::​row(const QListWidgetItem * item) const</div>
<br>
在图形界面,如果希望根据列表控件在屏幕显示的相对坐标位置(以列表控件内部左上角为原点)来获取条目,使用如下函数:<br>
<div class="code">QListWidgetItem * QListWidget::​itemAt(const QPoint &amp;
p) const</div>
<div class="code">QListWidgetItem * QListWidget::​itemAt(int x, int y) const</div>
反过来,如果根据已知条目,获取这个条目占据的矩形区域,使用如下函数:<br>
<div class="code">QRect QListWidget::​visualItemRect(const QListWidgetItem *
item) const</div>
<br>
(4)当前选中条目的操作<br>
获取列表控件当前选中条目的函数如下:<br>
<div class="code">QListWidgetItem * QListWidget::​currentItem() const //当前选中
条目</div>
<div class="code">int QListWidget::​currentRow() const&nbsp; //当前选中的行号</div>
如果当前没有选中的条目,那么返回的指针为 NULL,返回的序号为 -1 ,代码里要注意判断返回值。<br>
<br>
设置已存在的某个条目为选中状态,使用函数:<br>
<div class="code"> void QListWidget::​setCurrentItem(QListWidgetItem *
item)&nbsp;&nbsp;&nbsp; //设置当前选中条目为 item</div>
<div class="code">void QListWidget::​setCurrentItem(QListWidgetItem * item,
QItemSelectionModel::SelectionFlags command)</div>
<div class="code">void QListWidget::​setCurrentRow(int row,
QItemSelectionModel::SelectionFlags command)//设置当前选中行为 row</div>
<div class="code">void QListWidget::​setCurrentItem(QListWidgetItem * item,
QItemSelectionModel::SelectionFlags command)</div>
第二个和第四个设置函数有个 SelectionFlags 类型的参数
command,这个参数决定选中的方式,是要选中QItemSelectionModel::Select ,还是取消选中
QItemSelectionModel::Deselect,还有其他选中方式,等到表格控件一节再详细列出来。<br>
如果当前选中的条目发生变化,会触发如下三个信号,可以根据实际用途选择合适的信号:<br>
<div class="code">void QListWidget::​currentItemChanged(QListWidgetItem *
current, QListWidgetItem * previous)</div>
<div class="code">void QListWidget::​currentRowChanged(int currentRow)</div>
<div class="code">void QListWidget::​currentTextChanged(const QString &amp;
currentText)</div>
注意参数里的指针有可能为空值,序号可能为 -1,字符串也可能是空串,一定要注意判断非法的参数值。<br>
<br>
本章的三个控件都可以设置选中模式,比如单选模式,一次只能选中一个条目,多选模式,一次可以选中多个条目等等,详细的选中模式在放到表格控件一节讲解,因为表格
中涉及的选中模式较多,一块讲解。本节的列表控件默认情况下,选中模式为单选 QAbstractItemView::SingleSelection,以上的
*current* 等函数都是基于默认的单选模式的。<br>
<br>
如果需要用到多选模式,可以设置 selectionMode 属性为
QAbstractItemView::ExtendedSelection,这种扩展选中模式类似常见的文件资源管理器的选中模式,可以使用 Ctrl 或
Shift 加鼠标点击实现多选:<br>
<div class="code">void setSelectionMode(QAbstractItemView::SelectionMode
mode)&nbsp; //设置选中模式</div>
<div class="code">QAbstractItemView::SelectionMode&nbsp;&nbsp;
&nbsp;selectionMode() const&nbsp;&nbsp;&nbsp;&nbsp; //获取选中模式</div>
QAbstractItemView 是本章所有控件的抽象基类,本章后面控件也有类似的选中模式设置,如果把列表控件设置成多选模式,那么可以用如下函数获取同
时选中的多个条目:<br>
<div class="code">QList&lt;QListWidgetItem *&gt;
QListWidget::​selectedItems() const</div>
不论单选还是多选模式,条目选中情况有任何变化时,会触发如下信号:<br>
<div class="code">void QListWidget::​itemSelectionChanged()</div>
<br>
(5)条目查找和排序<br>
如果需要根据文本查找匹配的条目,使用如下函数:<br>
<div class="code">QList&lt;QListWidgetItem *&gt;
QListWidget::​findItems(const QString &amp; text, Qt::MatchFlags flags)
const</div>
该函数第一个参数 text 是要查找的模板子串,第二个参数是匹配标志,Qt::MatchFlags
是非常通用的枚举类型,不仅可用于字符串匹配,还能用于其他类型变量的匹配,Qt::MatchFlags 包含关于查找匹配的多种方式的枚举值:<br>
<br>
<table class="tabel">
<tbody>
<tr class="d1">
<td style="width: 200px;" align="center"><b>Qt::​MatchFlags 枚举常量</b></td>
<td style="width: 200px;" align="center"><b>数值</b></td>
<td align="center"><b> 描述</b></td>
</tr>
<tr>
<td>Qt::MatchExactly</td>
<td> 0 </td>
<td> 精确匹配,执行基于 QVariant 的匹配。 </td>
</tr>
<tr class="d1">
<td>Qt::MatchFixedString</td>
<td> 8 </td>
<td> 执行基于字符串的匹配,如果不指定 MatchCaseSensitive,默认是大小写不敏感。 </td>
</tr>
<tr>
<td>Qt::MatchContains</td>
<td> 1 </td>
<td> 条目包含要查找的模板子串。 </td>
</tr>
<tr class="d1">
<td>Qt::MatchStartsWith</td>
<td> 2 </td>
<td> 条目以要查找的模板子串打头。 </td>
</tr>
<tr>
<td>Qt::MatchEndsWith</td>
<td> 3 </td>
<td> 条目以要查找的模板子串结尾。 </td>
</tr>
<tr class="d1">
<td>Qt::MatchCaseSensitive</td>
<td> 16 </td>
<td> 查找时大小写敏感。 </td>
</tr>
<tr>
<td>Qt::MatchRegExp</td>
<td> 4 </td>
<td> 根据正则表达式模板子串匹配字符串。 </td>
</tr>
<tr class="d1">
<td>Qt::MatchWildcard</td>
<td> 5 </td>
<td> 根据通配符模板子串(如 *.txt)匹配字符串。 </td>
</tr>
<tr>
<td>Qt::MatchWrap</td>
<td> 32 </td>
<td> 执行回绕查找,当查找到最后一个条目时返回到第一个的条目继续查找,直到所有的条目都检查一遍。 </td>
</tr>
<tr class="d1">
<td>Qt::MatchRecursive</td>
<td> 64 </td>
<td> 递归查找,遍历所有子条目。 </td>
</tr>
</tbody>
</table>
<br>
后面两节的表格控件和树形控件也有类似的查找函数 ​findItems() ,第二个匹配标志参数也是一样的类型。<br>
<br>
列表控件的自动排序是通过 sortingEnabled 属性来控制,获取和设置函数如下:<br>
<div class="code">bool isSortingEnabled() const</div>
<div class="code">void setSortingEnabled(bool enable)</div>
列表控件条目默认是不排序的,如果希望自动按照字典序排序,调用 setSortingEnabled(true) 即可。另外还可以手动对列表控件现有条目排
序:<br>
<div class="code">void QListWidget::​sortItems(Qt::SortOrder order =
Qt::AscendingOrder)</div>
Qt::AscendingOrder 是按升序排列,Qt::DescendingOrder 是按降序排列。<br>
<br>
(6)条目显示和运行时条目编辑<br>
关于列表控件 QListWidget 和里面的条目 QListWidgetItem,需要注意条目 QListWidgetItem
仅仅是数据,不是控件或子控件,列表控件根据多个 QListWidgetItem 对象,来呈现条目里的数据,只有列表控件自己是控件实体。<br>
列表控件默认以自己的方式呈现条目数据,比如白底黑字的普通条目显示,如果要按照特殊的子控件来显示字符串,比如用 QLabel
对象显示条目数据,可以用如下函 数:<br>
<div class="code">void QListWidget::​setItemWidget(QListWidgetItem * item,
QWidget * widget)</div>
列表控件会同时拥有 item 数据条目和用于显示 item 的子控件 widget。注意这里的子控件 widget
只有静态显示功能,如果用按钮作为显示子控件,那么按钮是不可点击的。如果希望自己定制一个能交互操作的子条目显示控件,需要使用&nbsp;
QListView 并子类化 QItemDelegate 类,这些复杂的等到模型视图章节再讲。<br>
<br>
对于本节列表控件,如果要获取 ​setItemWidget() 函数指定某个条目的显示子控件,使用如下函数:<br>
<div class="code">QWidget * QListWidget::​itemWidget(QListWidgetItem * item)
const</div>
如果要删除上面 ​setItemWidget() 指定的特殊显示控件,使用函数:<br>
<div class="code">void QListWidget::​removeItemWidget(QListWidgetItem *
item)</div>
特殊的显示子控件移除后,该条目就还按照列表控件原来的普通条目显示。<br>
<br>
如果希望在程序运行时编辑列表控件的条目,有两种方式,本小节先讲第一种(第二种是设置条目自身的特性标志),手动打开条目的文本编辑器(这个编辑器是列表控件自
带功能,与 ​​setItemWidget 设置的显示子控件没关系):<br>
<div class="code">void QListWidget::​openPersistentEditor(QListWidgetItem *
item)</div>
这个函数名是打开条目的持续编辑器,持续的意思是如果不调用关闭函数,该条目的编辑器会一直开启,关闭这个持续编辑器使用如下函数:<br>
<div class="code">void QListWidget::​closePersistentEditor(QListWidgetItem *
item)</div>
一般可以在检测到条目激活信号(itemActivated)时调用打开函数 ​openPersistentEditor() ,在当前条目变化(
currentItemChanged)时调用关闭函数 ​closePersistentEditor() 。
使用这一对开关持续编辑器函数涉及到编写多个信号的槽函数,使用比较麻烦,建议用后面第二小节介绍的条目标 志位和
QListWidget::​editItem(QListWidgetItem * item) 实现条目的可编辑功能。<br>
<br>
(7)其他信号和槽函数<br>
除了上面关于当前条目变化和选中条目变化的信号,条目还有激活、单击、双击等信号,罗列如下:<br>
<div class="code">void QListWidget::​itemActivated(QListWidgetItem *
item)&nbsp; //激活信号</div>
当用户点击或双击条目时,条目会被激活,具体哪些操作会激活条目,要根据操作系统设置来定,比如 Windows 一般是双击打开激活,KDE
桌面通常是单击打开激活。另外,系统的快捷键也可以激活条目,如 Windows 和 Linux X11 桌面是回车键激活,Mac OS X 是
Ctrl+0 ,一般激活信号用于开启编辑等操作。<br>
<div class="code">void QListWidget::​itemChanged(QListWidgetItem *
item)&nbsp;&nbsp; //条目内容发生变化</div>
注意这是条目内容变化的信号,不是选中状态变化,程序如果在运行时改变了条目文本内容,比如持续编辑器修改了文本,会触发这个信号。<br>
剩下几个单击、双击、进入、按压等信号意义比较直白,不详细解释了:<br>
<div class="code">void QListWidget::​itemClicked(QListWidgetItem *
item)&nbsp;&nbsp; //条目单击信号</div>
<div class="code">void QListWidget::​itemDoubleClicked(QListWidgetItem *
item)&nbsp; //条目双击信号</div>
<div class="code">void QListWidget::​itemEntered(QListWidgetItem *
item)&nbsp; //鼠标追踪时进入条目的信号,一般用不着</div>
<div class="code">void QListWidget::​itemPressed(QListWidgetItem *
item)&nbsp; //鼠标按键在条目上处于按下状态时发的信号</div>
<br>
列表控件的槽函数除了前面讲过的 clear()
槽函数用于清空所有条目,还有个比较实用的条目滚动函数,列表控件自带滚动条,当条目总数超出控件矩形能呈现的数目时,滚动条自动出现,通过滚动条支持更多的条目显示。使
用如下槽函数可 以让列表控件滚动到想显示的某个条目位置:<br>
<div class="code">void QListWidget::​scrollToItem(const QListWidgetItem *
item, QAbstractItemView::ScrollHint hint = EnsureVisible)</div>
第一个参数 item 就是想显示出来的条目,第二个参数是滚动显示方式,默认是
QAbstractItemView::EnsureVisible,即保证指定条目显示出来,还有其他的滚动显示方式:<br>
<br>
<table class="tabel">
<tbody>
<tr class="d1">
<td style="width: 360px;" align="center"><b>QAbstractItemView::​
ScrollHint 枚举常量</b></td>
<td style="width: 140px;" align="center"><b>数值</b></td>
<td align="center"><b> 描述</b></td>
</tr>
<tr>
<td>QAbstractItemView::EnsureVisible</td>
<td> 0 </td>
<td> 滚动到指定条目能显示出来即可。 </td>
</tr>
<tr class="d1">
<td>QAbstractItemView::PositionAtTop</td>
<td> 1 </td>
<td> 滚动直到将指定条目显示到可视区域的顶部。 </td>
</tr>
<tr>
<td>QAbstractItemView::PositionAtBottom </td>
<td> 2 </td>
<td> 滚动直到将指定条目显示到可视区域的底部。 </td>
</tr>
<tr class="d1">
<td>QAbstractItemView::PositionAtCenter</td>
<td> 3 </td>
<td> 滚动直到将指定条目显示到可视区域的中间。 </td>
</tr>
</tbody>
</table>
<br>
关于列表控件的函数介绍这些,下面讲解与之配合使用的条目类 QListWidgetItem。<br>
<br>
<div class="os2">8.1.2 QListWidgetItem</div>
<br>
QListWidgetItem 专门用于表示列表控件 QListWidget 的数据条目,注意 QListWidgetItem
是一个纯数据类,不是控件,没有基类,也就没有信号和槽函数。QListWidgetItem 可以直接用数据流 QDataStream 读写。<br>
QListWidgetItem 不单单有字符串,还可以有自己的图标、复选框等特性,列表控件会根据条目对象的丰富特性来呈现数据并进行交互操作。<br>
(1)首先来看看列表控件条目的构造函数:<br>
<div class="code">QListWidgetItem(QListWidget * parent = 0, int type = Type)</div>
<div class="code">QListWidgetItem(const QString &amp; text, QListWidget *
parent = 0, int type = Type)</div>
<div class="code">QListWidgetItem(const QIcon &amp; icon, const QString
&amp; text, QListWidget * parent = 0, int type = Type)</div>
那第三个构造函数的参数来讲,icon 是条目显示的图标,text 是条目文本,parent 是条目隶属的列表控件,type 是条目的自定义类型。<br>
如果在构造函数指定了条目隶属的列表控件,那么这个条目会自动添加到列表控件末尾,而不需要调用列表控件的 add*() 和 insert*()函数,比如:<br>
<div class="code">&nbsp;&nbsp;&nbsp; new QListWidgetItem(tr("Hazel"),
listWidget);</div>
只需要上面一句代码,"Hazel" 条目就自动显示在列表控件 listWidget 里面了,只要指定所隶属的列表控件,新建的条目自动添加并显示在末尾。<br>
<br>
(2)条目的复制方式,有三个函数可以实现:<br>
<div class="code">QListWidgetItem(const QListWidgetItem &amp; other)&nbsp;
//复制构造函数</div>
<div class="code">QListWidgetItem &amp; operator=(const QListWidgetItem
&amp; other) // = 赋值函数</div>
<div class="code">virtual QListWidgetItem *&nbsp; clone() const&nbsp; //克隆函数</div>
复制构造函数和 = 赋值函数 函数原理是一样的,它们除了 type() 和 listWidget()
函数指定的两个数据不复制,其他的数据都复制。type() 是条目的自定义类型,listWidget() 是该条目所隶属的列表控件。<br>
而克隆函数 clone() 会精确复制所有数据,如果原条目隶属某个列表控件,克隆出来的也会自动隶属该列表控件,自定义条目类型也一样。<br>
顺便说一下列表条目的比较函数:<br>
<div class="code">virtual bool operator&lt;(const QListWidgetItem &amp;
other) const</div>
只有一个小于号函数,是比较列表条目文本的字典序先后关系,没有等于号函数和大于号函数,如果确实用到条目文本比较,建议直接用 QString 变量进行比较。<br>
<br>
(3)QListWidgetItem 的功能函数与内部数据<br>
QListWidgetItem 绝大部分的功能函数都是围绕内部数据处理的,QListWidgetItem
内部的数据大致分为两类:第一类是以数据角色形式管理的通用数据,这些数据自动参与 QDataStream
数据流的读写;第二类是非通用数据,不参与数据流读写,与 QListWidgetItem 和 QListWidget 自身特性有关。<br>
<br>
● 第一类:QListWidgetItem 的通用数据<br>
通用数据是以数据角色与数据变量一一对应的形式存储管理,比如设置文本 setText()、设置图标 setIcon()
等函数,其本质都是根据各自的角色调用通用设置数据的函数:<br>
<div class="code">virtual void setData(int role, const QVariant &amp; value)</div>
也可以根据角色来获取各个数据变量:<br>
<div class="code">virtual QVariant data(int role) const</div>
<br>
查看列表控件源码文件:<br>
&nbsp;C:\Qt\Qt5.4.0\5.4\Src\qtbase\src\widgets\itemviews\qlistwidget.h<br>
可以看到关于文本变量的函数 text() 和 setText() 源代码:<br>
<div class="code">inline QString text() const<br>
&nbsp; { return data(Qt::DisplayRole).toString(); }</div>
<div class="code">inline void QListWidgetItem::setText(const QString
&amp;atext)<br>
&nbsp; { setData(Qt::DisplayRole, atext); }</div>
关于 QListWidgetItem 内部通用数据的获取和设置函数、数据角色列表如下:<br>
<br>
<table class="tabel">
<tbody>
<tr class="d1">
<td style="width: 110px;" align="center"><b>获取函数</b></td>
<td style="width: 280px;" align="center"><b>设置函数</b></td>
<td style="width: 150px;" align="center"><b>数据角色</b></td>
<td align="center"><b> 描述 </b></td>
</tr>
<tr>
<td>text()</td>
<td> setText(const QString &amp;text) </td>
<td> Qt::DisplayRole </td>
<td> 条目显示的文本。 </td>
</tr>
<tr class="d1">
<td>icon()</td>
<td> setIcon(const QIcon &amp;icon) </td>
<td> Qt::DecorationRole </td>
<td> 条目显示的图标。 </td>
</tr>
<tr>
<td>statusTip()</td>
<td> setStatusTip(const QString &amp;statusTip) </td>
<td> Qt::StatusTipRole </td>
<td> 如果主界面有状态栏,鼠标悬停在该条目上时显示该状态信息到状态栏。 </td>
</tr>
<tr class="d1">
<td>toolTip()</td>
<td> setToolTip(const QString &amp;toolTip) </td>
<td> Qt::ToolTipRole </td>
<td> 鼠标悬停在该条目上时显示的工具提示信息。 </td>
</tr>
<tr>
<td>whatsThis()</td>
<td> setWhatsThis(const QString &amp;whatsThis) </td>
<td> Qt::WhatsThisRole </td>
<td> 如果主界面窗口标题栏有?帮助按钮,点击帮助按钮再点击该条目会显示该帮助信息。 </td>
</tr>
<tr class="d1">
<td>font()</td>
<td> setFont(const QFont &amp;font) </td>
<td> Qt::FontRole </td>
<td> 显示条目文本用的字体。 </td>
</tr>
<tr>
<td>textAlignment()</td>
<td> setTextAlignment(int alignment) </td>
<td> Qt::TextAlignmentRole </td>
<td> 文本的对齐方式。 </td>
</tr>
<tr class="d1">
<td>backgroundColor()</td>
<td> setBackgroundColor(const QColor &amp;color)</td>
<td> Qt::BackgroundColorRole </td>
<td> 文本背景色。 </td>
</tr>
<tr>
<td>textColor()</td>
<td> setTextColor(const QColor &amp;color)</td>
<td> Qt::TextColorRole </td>
<td> 文字颜色。 </td>
</tr>
<tr class="d1">
<td>background()</td>
<td> setBackground(const QBrush &amp;brush) </td>
<td> Qt::BackgroundRole </td>
<td> 条目的背景画刷。 </td>
</tr>
<tr>
<td>foreground()</td>
<td> setForeground(const QBrush &amp;brush) </td>
<td> Qt::ForegroundRole </td>
<td> 条目的前景画刷。 </td>
</tr>
<tr class="d1">
<td>checkState()</td>
<td> setCheckState(Qt::CheckState state)</td>
<td> Qt::CheckStateRole </td>
<td> 条目自带的复选框选中状态,可以是三态复选框。 </td>
</tr>
<tr>
<td>sizeHint()</td>
<td> setSizeHint(const QSize &amp;size) </td>
<td> Qt::SizeHintRole </td>
<td> 条目显示的建议尺寸。 </td>
</tr>
</tbody>
</table>
<br>
QListWidgetItem 可以直接用数据流 QDataStream
读写,涉及到读写的内部数据就是上表所列举的以角色形式表述的数据,QListWidgetItem 通过两个外部全局运算符重载函数支持
QDataStream 数据流读写:<br>
<div class="code">QDataStream &amp;operator&lt;&lt;(QDataStream &amp;out,
const QListWidgetItem &amp;item)</div>
<div class="code">QDataStream &amp;operator&gt;&gt;(QDataStream &amp;in,
QListWidgetItem &amp;item)</div>
使用运算符的形式比较方便,当然也可以用 QListWidgetItem 内部的读写函数:<br>
<div class="code">void QListWidgetItem::​read(QDataStream &amp; in)</div>
<div class="code">void QListWidgetItem::​write(QDataStream &amp; out) const</div>
&nbsp;<br>
QListWidgetItem 内部采用私有的 QVector 向量存储通用数据的 role 和 value 对:<br>
<div class="code"><span style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QVector</span><span
style=" color:#000000;">&lt;</span><span style=" color:#800080;">QWidgetItemData</span><span
style=" color:#000000;">&gt;</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#800000;">values</span><span style=" color:#000000;">;</span></div>
条目通用数据的读写就是读写私有向量 values,其中 QWidgetItemData 内部包含 role 和 value 成员变量:<br>
<div class="code"><span style=" color:#808000;">class</span><span style=" color:#c0c0c0;">
</span><span style=" color:#800080;">QWidgetItemData</span>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#808000;">public</span><span style=" color:#000000;">:</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">inline</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QWidgetItemData</span><span
style=" color:#000000;">()</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">:</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#800000;">role</span><span style=" color:#000000;">(-</span><span
style=" color:#000080;">1</span><span style=" color:#000000;">)</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">{}</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">inline</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QWidgetItemData</span><span
style=" color:#000000;">(</span><span style=" color:#808000;">int</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">r</span><span style=" color:#000000;">,</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#800080;">QVariant</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">v</span><span style=" color:#000000;">)</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">:</span><span style=" color:#c0c0c0;"> </span><span style=" color:#800000;">role</span><span
style=" color:#000000;">(</span><span style=" color:#000000;">r</span><span style=" color:#000000;">),</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#800000;">value</span><span
style=" color:#000000;">(</span><span style=" color:#000000;">v</span><span style=" color:#000000;">)</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">{}</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">int</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#800000;">role</span><span style=" color:#000000;">;</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QVariant</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#800000;">value</span><span
style=" color:#000000;">;</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">inline</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">bool</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">operator</span><span style=" color:#000000;">==(</span><span
style=" color:#808000;">const</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#800080;">QWidgetItemData</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">&amp;</span><span style=" color:#000000;">other</span><span
style=" color:#000000;">)</span><span style=" color:#c0c0c0;"> </span><span style=" color:#808000;">const</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">{</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#808000;">return</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#800000;">role</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">==</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">other</span><span
style=" color:#000000;">.</span><span style=" color:#800000;">role</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">&amp;&amp;</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#800000;">value</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">==</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">other</span><span
style=" color:#000000;">.</span><span style=" color:#800000;">value</span><span
style=" color:#000000;">;</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">}</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">};</span></pre>
</div>
在 8.2 节表格控件的单元格条目也是类似的私有向量存储 role 和 value 对。<br>
<br>
● 第二类:QListWidgetItem 的非通用数据<br>
条目自定义类型:<br>
<div class="code">int QListWidgetItem::​type() const</div>
这个条目类型只能在构造函数指定,指定之后不能修改,默认值为 QListWidgetItem::Type (数值
0),如果程序员希望自己区分列表控件条目的类型,那么可以自己定义大于 QListWidgetItem::UserType (数值
1000)的类型值,一般用在 QListWidgetItem 派生类里面。<br>
<br>
条目所隶属的列表控件:<br>
<div class="code">QListWidget * QListWidgetItem::​listWidget() const</div>
条目自身不能修改所隶属的列表控件,要通过列表控件的删除函数 QListWidget::​takeItem(int row) 才能解除隶属关系。<br>
<br>
列表条目本身的选中状态(与复选框无关,是用户在列表控件点击条目的高亮选中状态):<br>
<div class="code">void QListWidgetItem::setSelected(bool select)</div>
<div class="code">bool QListWidgetItem::isSelected() const</div>
一般是用户在列表控件图形界面点击哪个条目,哪个条目就处于高亮选中状态,这里可以用条目自身的函数设置高亮选中状态。<br>
<br>
条目在列表控件里面显示或者隐藏:<br>
<div class="code">void QListWidgetItem::​setHidden(bool hide)</div>
<div class="code">bool QListWidgetItem::​isHidden() const</div>
<br>
条目的特性标志:<br>
<div class="code">void QListWidgetItem::​setFlags(Qt::ItemFlags flags)</div>
<div class="code">Qt::ItemFlags QListWidgetItem::​flags() const</div>
flags 会决定条目的工作特性,比如是否有三态复选框,是否在用户双击该条目时开启文本编辑器等等,Qt::ItemFlags 枚举值见下面表格:<br>
<br>
<table class="tabel">
<tbody>
<tr class="d1">
<td style="width: 200px;" align="center"><b>Qt::​ItemFlags 枚举常量</b></td>
<td style="width: 100px;" align="center"><b>数值</b></td>
<td align="center"><b> 描述</b></td>
</tr>
<tr>
<td>Qt::NoItemFlags</td>
<td> 0 </td>
<td> 不设置任何特性,条目会处于完全的不可用状态。 </td>
</tr>
<tr class="d1">
<td>Qt::ItemIsSelectable</td>
<td> 1 </td>
<td> 条目本身可以被高亮选中。 </td>
</tr>
<tr>
<td>Qt::ItemIsEditable </td>
<td> 2 </td>
<td> 条目可以被编辑,比如用户双击条目时自动启用文本编辑器。 </td>
</tr>
<tr class="d1">
<td>Qt::ItemIsDragEnabled</td>
<td> 4 </td>
<td> 条目可以被拖拽出去。 </td>
</tr>
<tr>
<td>Qt::ItemIsDropEnabled </td>
<td> 8 </td>
<td> 条目可以作为拖拽的目的地。 </td>
</tr>
<tr class="d1">
<td>Qt::ItemIsUserCheckable</td>
<td> 16 </td>
<td> 条目可以有复选框,用户能勾选复选框。 </td>
</tr>
<tr>
<td>Qt::ItemIsEnabled </td>
<td> 32</td>
<td> 条目处于可用状态。 </td>
</tr>
<tr class="d1">
<td>Qt::ItemIsTristate</td>
<td> 64 </td>
<td> 条目的复选框可以有三种勾选状态:选中、非选中、部分选中。 </td>
</tr>
<tr>
<td>Qt::ItemNeverHasChildren </td>
<td> 128 </td>
<td> 条目不能有子条目(指树形控件)。 </td>
</tr>
</tbody>
</table>
<br>
上表中的 Qt::ItemFlags 也适用于后面 8.2 节的表格控件条目和 8.3
节的树形控件条目,表格条目和树形条目也都有一样的条目标志位设置函数,功能与本节列表条目一样,参数也一样。<br>
列表控件条目默认的特性标志为同时启用四个:<br>
Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled |
Qt::ItemIsDragEnabled<br>
<br>
按照默认标志位,列表条目是可以有复选框进行勾选的,调用 QListWidgetItem::​setCheckState()
函数可以让列表条目的复选框显示出来。<br>
如果要设置三态复选框,可以使用下面的代码:<br>
<div class="code"><span style=" color:#c0c0c0;">&nbsp;&nbsp;&nbsp; </span><span
style=" color:#000000;">item</span><span style=" color:#000000;">-&gt;</span><span
style=" color:#000000;">setFlags</span><span style=" color:#000000;">(</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">(</span><span
style=" color:#000000;">item</span><span style=" color:#000000;">-&gt;</span><span
style=" color:#000000;">flags</span><span style=" color:#000000;">())</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">|</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">Qt</span><span
style=" color:#000000;">::</span><span style=" color:#800080;">ItemIsTristate</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">);</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//开启三态复选</span>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">item</span><span
style=" color:#000000;">-&gt;</span><span style=" color:#000000;">setCheckState</span><span
style=" color:#000000;">(</span><span style=" color:#c0c0c0;"> </span><span style=" color:#800080;">Qt</span><span
style=" color:#000000;">::</span><span style=" color:#800080;">Unchecked</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">);</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;">//显示复选框</span></pre>
</div>
如果希望用户在双击条目时,自动开启条目文本的编辑器,可以用下面代码:<br>
<div class="code"><span style=" color:#c0c0c0;">&nbsp;&nbsp;&nbsp; </span><span
style=" color:#000000;">item</span><span style=" color:#000000;">-&gt;</span><span
style=" color:#000000;">setFlags</span><span style=" color:#000000;">(</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">(</span><span
style=" color:#000000;">item</span><span style=" color:#000000;">-&gt;</span><span
style=" color:#000000;">flags</span><span style=" color:#000000;">())</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">|</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">Qt</span><span
style=" color:#000000;">::</span><span style=" color:#800080;">ItemIsEditable</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">);</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//双击条目会自动
开启文本编辑器</span></div>
因为可以设置条目的 Qt::ItemIsEditable 标志位,所以列表控件 QListWidget 的一对持续编辑器函数&nbsp;
openPersistentEditor() 和 closePersistentEditor()
一般不需要手动调用,直接设置条目自身的可编辑标志位就行了。<br>
对于启用可编辑标志位的条目,如果希望通过代码开启条目的编辑,可以调用列表控件的 ​editItem()
函数来实现,而不需要使用一对开关持续编辑器函数那么麻烦:<br>
<div class="code">void QListWidget::​editItem(QListWidgetItem * item)</div>
<br>
这里说明一下:<span style="font-weight: bold;">列表条目本身是可以存储复选框的勾选状态数值,而条目显示的复选框是由列表控
件绘制并提供,列表条目自身不是控件,也不包含子控件。类似地,列表控件根据 Qt::ItemIsEditable
标志位检查是否需要为条目提供文本编辑器</span><br>
<br>
在 QtCreator 设计模式和 Qt 设计师界面,都可以直接编辑列表控件、表格控件、树形控件的条目,右击这些控件,在右键菜单选择“编辑项目 ...”
菜单项即可,上面提到的条目数据,不管是通用的还是非通用的,只要可以修改,几乎都能在图形设计界面可视化编辑,等会例子中再示范。后面 8.2 节表格控件和
8.3
节的树形控件的条目有很多与列表控件类似的数据格式、接口函数、特性标志等,本节的表格关于函数和常量的枚举表格在后面两节都有用到,很多内容是一样的。关于列表控件和条
目的内容介绍到这,下面看看例子。<br>
<br>
<div class="os2">8.1.3 游戏装备列表示例</div>
<br>
在 7.1.5
文件系统浏览示例,我们就已经使用到列表控件了,并且条目既有图标也有文本显示,读者可以复习一下前面的示例。本小节示例是一个可编辑的游戏装备列表,学习
QtCreator 设计模式和 Qt 设计师里面列表控件的可视化编辑,而程序运行时也可以自己选择装备图标、设置游戏装备名称,并支持条目数据的保存和加载。<br>
在开始例子之前,先下载一个游戏装备图标压缩包: <br>
<a href="https://lug.ustc.edu.cn/sites/qtguide/QtProjects/ch08/dotaitems/dotasytb.zip"
target="new">
https://lug.ustc.edu.cn/sites/qtguide/QtProjects/ch08/dotaitems/dotasytb.zip
</a> <br>
压缩包解压之后,有个 DOTA-ITEM
文件夹,里面是游戏装备图标,我们抽取蝴蝶(fgfh.jpg)、金箍棒(odef.jpg)、大炮(rman.jpg)
三个图标备用,例子内嵌资源使用这三个图标,然后我们开始这个例子的学习。<br>
打开 QtCreator,新建一个 Qt Widgets Application 项目,在新建项目的向导里填写:<br>
①项目名称 dotaitems,创建路径 D:\QtProjects\ch08,点击下一步;<br>
②套件选择里面选择全部套件,点击下一步;<br>
③基类选择 QWidget,点击下一步;<br>
④项目管理不修改,点击完成。<br>
<br>
在开始图形界面编辑之前,我们先添加图标和资源文件:<br>
在源码文件夹 D:\QtProjects\ch08\dotaitems 里新建一个叫 icons 的子文件夹,然后把三个图标文件
fgfh.jpg、odef.jpg、rman.jpg 放到 icons 子文件夹。<br>
然后在 QtCreator 左边项目管理面板,右击 dotaitems 项目名称,右键菜单选中 "添加新文件" ,弹出新建文件对话框,<br>
<center><img src="images/ch08/ch08-01-02.png" alt="rc1" width="800"></center>
选择新建 Qt Resource File,点击 "Choose..." 按钮,进入如下界面,<br>
<center><img src="images/ch08/ch08-01-03.png" alt="rc2" width="800"></center>
名称填写 icons,路径用当前项目文件夹,点击 "下一步",<br>
<center><img src="images/ch08/ch08-01-04.png" alt="rc3" width="800"></center>
项目管理界面不用修改,点击完成。进入 QtCreator 资源文件编辑界面,我们在左边项目管理面板右击 icons.qrc 文件名,<br>
<center><img src="images/ch08/ch08-01-05.png" alt="rc4" width="800"></center>
右键菜单选择 "添加现有文件",在弹出的文件对话框,选择 icons 子文件夹里三个图标文件添加,添加好之后如下图所示:<br>
<center><img src="images/ch08/ch08-01-06.png" alt="rc5" width="800"></center>
这样图标和资源文件就编辑好了,保存该资源文件,关闭该文件。接下来我们编辑 ui 界面文件。<br>
<br>
我们打开 widget.ui 界面文件,按照下图拖入控件:<br>
<center><img src="images/ch08/ch08-01-07.png" alt="ui" width="800"></center>
界面分为左边和右边两个大部分:<br>
左边上方是列表控件,对象名为 listWidget;左下是单行编辑器,对象名为 lineEditToolTip,左边两个控件按照垂直布局排布。<br>
右边是六个按钮,第一个按钮文本是 "添加",对象名 pushButtonAdd;第二个按钮文本是 "删除",对象名
pushButtonDel;第三个按钮文本是 "切换显示模式",对象名 pushButtonViewMode;第四个按钮文本为 "加载",对象名
pushButtonLoad;第五个按钮文本为 "保存",对象名为 pushButtonSave;在 "保存"
按钮下面是一个垂直的空白条,用默认的对象名即可;第六个按钮文本为 "编辑工具提示",对象名为
pushButtonEditToolTip。右边的控件也是按照垂直布局器排布,主界面是按照水平布局器排布。<br>
<br>
这里解释一下这些控件的用途:<br>
列表控件显示游戏装备的图标和名称列表,初始时显示资源文件内嵌的三个游戏装备;<br>
"添加" 按钮可以从磁盘添加新的游戏装备图标和装备名;"删除" 按钮是从列表删除一个条目;<br>
"切换显示模式" 按钮用于控制列表控件的显示方式,是小图标文字模式,还是大图标模式;<br>
"保存" 按钮是将当前列表控件条目保存为自定义的 *.item 数据流文件,"加载" 按钮是加载之前存的文件;<br>
单行编辑器和 "编辑工具提示" 按钮,是设置列表当前选中条目的工具提示信息,相当于游戏装备描述信息。<br>
<br>
我们现在来学一下让列表控件初始时显示三个装备条目,在 QtCreator 和 Qt 设计师里面,可以直接为列表控件、表格控件、树形控件(都是
Item-Based)添加条目,这些条目可以自动在程序启动时显示。我们右击列表控件,在右键菜单看到 "编辑项目..." 菜单项:<br>
<center><img src="images/ch08/ch08-01-08.png" alt="item1" width="800"></center>
"编辑项目..." 这个菜单项的用途就是编辑条目的意思,点击之后看到如下条目编辑对话框:<br>
<center><img src="images/ch08/ch08-01-09.png" alt="item2"></center>
绿色加号图标按钮就是添加新的条目,我们添加三个条目,条目文本为 "蝴蝶"、"金箍棒"、"大炮" :<br>
<center><img src="images/ch08/ch08-01-10.png" alt="item3"></center>
条目不仅有文字,还可以编辑条目的 "属性",就是上面小节介绍的 QListWidgetItem 通用数据和非通用数据,点击 "属性"
按钮,可以看到条目的详细编辑内容:<br>
<center><img src="images/ch08/ch08-01-11.png" alt="item4"></center>
对于第一个条目 "蝴蝶" ,我们点击属性 icon,再点击 icon 右边一栏的小按钮,在菜单里点击 "选择资源" :<br>
<center><img src="images/ch08/ch08-01-12.png" alt="item5"></center>
然后我们选择蝴蝶的图标给该条目:<br>
<center><img src="images/ch08/ch08-01-13.png" alt="item6"></center>
添加之后,可以看到第一个条目有蝴蝶图标了:<br>
<center><img src="images/ch08/ch08-01-14.png" alt="item7"></center>
然后我们编辑蝴蝶条目的 toolTip ,可以自己在网上找点蝴蝶的描述信息填到该工具提示里面:<br>
<center><img src="images/ch08/ch08-01-15.png" alt="item8"></center>
上图设置的就是HTML丰富文本的工具提示信息,原本是从网页复制到 "多文本" 编辑模式里的,如果点击 "源" 编辑模式,可以看到 HTML 的源码:<br>
<div class="code">&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span
style=" font-family:'宋体,arial,sans-serif'; font-size:12px; color:#0090ff;
background-color:#121212;"&gt;+30点攻击力&lt;br/&gt;+30%攻速&lt;br/&gt;+30点敏
&lt;br/&gt;&lt;/span&gt;&lt;span style="
font-family:'宋体,arial,sans-serif'; font-size:12px; color:#66ffff;
background-color:#121212;"&gt;+35%的物理攻击闪避&lt;/span&gt;&lt;/p&gt;&lt;
/body&gt;&lt;/html&gt;</div>
编辑后点击确定,回到条目编辑界面,关于蝴蝶条目,还有其他的数据信息可以编辑,读者可以自己试试看,上文提到的条目数据几乎都可以在右边的属性编辑栏里面找到。<br>
<br>
然后我们如法炮制,为列表控件第二个、第三个条目添加图标和工具提示:<br>
<center><img src="images/ch08/ch08-01-16.png" alt="item9"></center>
<br>
金箍棒的描述信息也是丰富文本,HTML源码如下:
<div class="code">&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span
style=" font-family:'宋体,arial,sans-serif'; font-size:12px; color:#0090ff;
background-color:#121212;"&gt;+88点攻击力&lt;br/&gt;+15%攻速&lt;br/&gt;&lt;
/span&gt;&lt;span style=" font-family:'宋体,arial,sans-serif';
font-size:12px; color:#66ffff;
background-color:#121212;"&gt;被动:攻击不会落空(与某些法球冲突,可关闭该效果),攻击中有35%的机率造成0.01秒的晕眩并
且+100点附加伤害&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</div>
大炮的描述信息 HTML 源码如下:
<div class="code">&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span
style=" font-family:'宋体,arial,sans-serif'; font-size:12px; color:#0090ff;
background-color:#121212;"&gt;+81点攻击力&lt;br/&gt;25%机率造成2.4倍伤害&lt;br
/&gt;&lt;/span&gt;&lt;span style=" font-family:'宋体,arial,sans-serif';
font-size:12px; color:#ffff00;
background-color:#121212;"&gt;通俗称呼:大炮&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;
/html&gt;</div>
这些描述信息是从如下网站复制的,可以直接粘贴到丰富文本编辑对话框里面(在多文本模式粘贴):<br>
<a href="http://db.pcgames.com.cn/dota/item_864.html" target="new">
http://db.pcgames.com.cn/dota/item_864.html </a> <br>
<br>
由于支持丰富文本的工具提示,Qt
的其他控件或控件条目可以展示非常棒的工具提示效果,不仅仅是丰富文本,我们还可以为工具提示添加资源里的图片,以第三个大炮的工 具提示编辑框为例:<br>
<center><img src="images/ch08/ch08-01-17.png" alt="item10"></center>
我们在多文本编辑模式,先在文字前按回车键,在文字之前新加空白行,然后点击上面 "插入图像" 按钮,看到选择资源图片的对话框:<br>
<center><img src="images/ch08/ch08-01-18.png" alt="item11"></center>
我们选中第三个大炮的图片添加到工具提示里面,可以看到如下效果:<br>
<center><img src="images/ch08/ch08-01-19.png" alt="item12"></center>
这是大炮的工具提示信息预览,等程序编译运行后我们再看看实际效果。<br>
在工具提示添加大炮图片之后,可以看看工具提示 HTML 源码的变化:<br>
<div class="code">&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;img
src=":/icons/rman.jpg"/&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="
font-family:'宋体,arial,sans-serif'; font-size:12px; color:#0090ff;
background-color:#121212;"&gt;+81点攻击力&lt;br/&gt;25%机率造成2.4倍伤害&lt;br/&gt;&lt;
/span&gt;&lt;span style=" font-family:'宋体,arial,sans-serif';
font-size:12px; color:#ffff00;
background-color:#121212;"&gt;通俗称呼:大炮&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;
/html&gt;</div>
Qt编程中,一般支持丰富文本的控件或条目,都可以显示内嵌资源文件里的图片,内嵌资源里的图片供 HTML 引用的方式如下:<br>
<div class="code">&lt;img src=":/icons/rman.jpg"/&gt;</div>
除了以冒号打头的图片路径,其他与标准的 HTML 图片引用没区别。<br>
<br>
关于条目属性编辑的内容还有很多:<br>
<center><img src="images/ch08/ch08-01-20.png" alt="item13"></center>
除了条目的文本、图标、工具提示,还可以设置状态栏信息、帮助信息、字体、文本对齐、背景色、前景色、条目特性标志以及复选框勾选状态等等。无论是通过
QtCreator 设计模式或 Qt 设计师的可视化编辑设置条目,还是通过编写代码调整条目的数据,都是可行的,等会我们再学习一些关于设置条目数据的代码。<br>
关于列表控件条目的可视化编辑就介绍这些,读者可以自己试试,尤其是条目的特性标志,可以把条目设置为可编辑的 Editable
标志,等会我们通过代码来修改。<br>
<br>
编辑好列表控件的条目之后,我们回到原来的界面编辑,为各个控件添加槽函数。<br>
右击列表控件,在右键菜单选择 "转到槽..." ,添加 currentItemChanged(QListWidgetItem *,
QListWidgetItem *) 信号对应的槽函数:<br>
<center><img src="images/ch08/ch08-01-21.png" alt="slot1"></center>
然后再类似操作一遍,还是为列表控件添加槽函数,再添加 itemChanged(QListWidgetItem * )
信号对应的槽函数。列表控件对应的两个槽函数功能等会再详解。<br>
<br>
主界面右边还有六个按钮控件,为每个按钮都添加 clicked() 信号对应的槽函数:<br>
<center><img src="images/ch08/ch08-01-22.png" alt="slot3"></center>
槽函数添加完成后,保存界面文件,关闭界面文件,回到 QtCreator 代码编辑模式,开始编写例子的代码。<br>
<br>
我们首先编辑头文件 widget.h,主要添加两句头文件包含,其他的不修改:<br>
<div class="code"><span style=" color:#000080;">#ifndef</span><span style=" color:#c0c0c0;">
</span>WIDGET_H
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000080;">#define</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000080;">WIDGET_H</span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000080;">#include</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;">&lt;QWidget&gt;</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000080;">#include</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;">&lt;QListWidget&gt;</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;">//列表控件</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000080;">#include</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;">&lt;QListWidgetItem&gt;</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;">//列表控件条目</span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#808000;">namespace</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#800080;">Ui</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#808000;">class</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#800080;">Widget</span><span style=" color:#000000;">;</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">}</span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#808000;">class</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#800080;">Widget</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">:</span><span style=" color:#c0c0c0;"> </span><span style=" color:#808000;">public</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QWidget</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000080;">Q_OBJECT</span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#808000;">public</span><span style=" color:#000000;">:</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">explicit</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">Widget</span><span
style=" color:#000000;">(</span><span style=" color:#800080;">QWidget</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">*</span>parent<span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">=</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000080;">0</span><span style=" color:#000000;">);</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">~</span><span style=" font-style:italic; color:#000000;">Widget</span><span
style=" color:#000000;">();</span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#808000;">private</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#808000;">slots</span><span style=" color:#000000;">:</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">void</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">on_listWidget_currentItemChanged</span><span
style=" color:#000000;">(</span><span style=" color:#800080;">QListWidgetItem</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">*</span>current<span
style=" color:#000000;">,</span><span style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QListWidgetItem</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">*</span>previous<span
style=" color:#000000;">);</span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">void</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">on_listWidget_itemChanged</span><span
style=" color:#000000;">(</span><span style=" color:#800080;">QListWidgetItem</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">*</span>item<span
style=" color:#000000;">);</span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">void</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">on_pushButtonAdd_clicked</span><span
style=" color:#000000;">();</span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">void</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">on_pushButtonDel_clicked</span><span
style=" color:#000000;">();</span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">void</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">on_pushButtonViewMode_clicked</span><span
style=" color:#000000;">();</span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">void</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">on_pushButtonLoad_clicked</span><span
style=" color:#000000;">();</span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">void</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">on_pushButtonSave_clicked</span><span
style=" color:#000000;">();</span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">void</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">on_pushButtonEditToolTip_clicked</span><span
style=" color:#000000;">();</span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#808000;">private</span><span style=" color:#000000;">:</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">Ui</span><span
style=" color:#000000;">::</span><span style=" color:#800080;">Widget</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">*</span><span style=" color:#800000;">ui</span><span
style=" color:#000000;">;</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">};</span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000080;">#endif</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;">//</span><span style=" color:#c0c0c0;"> </span><span style=" color:#008000;">WIDGET_H</span></pre>
</div>
列表控件对应的槽函数在头文件声明中用到了列表条目,所以提前包含了 &lt;QListWidget&gt;
&lt;QListWidgetItem&gt; 两个类头文件,其他的代码都是自动生成的,不用修改。<br>
下面编辑源文件 widget.cpp ,添加实际的功能代码,这个文件代码比较多,我们逐个函数来看。<br>
首先是头文件包含和构造函数代码:<br>
<div class="code"><span style=" color:#000080;">#include</span><span style=" color:#c0c0c0;">
</span><span style=" color:#008000;">"widget.h"</span>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000080;">#include</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;">"ui_widget.h"</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000080;">#include</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;">&lt;QDebug&gt;</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000080;">#include</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;">&lt;QIcon&gt;</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;">//图标类</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000080;">#include</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;">&lt;QFileDialog&gt;</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;">//程序运行时可打开新图标文件</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000080;">#include</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;">&lt;QMessageBox&gt;</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;">//消息框</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000080;">#include</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;">&lt;QFile&gt;</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;">//文件类</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000080;">#include</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;">&lt;QDataStream&gt;</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;">//数据流,加载和保存条目数据</span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#800080;">Widget</span><span style=" color:#000000;">::</span><span
style=" color:#000000;">Widget</span><span style=" color:#000000;">(</span><span
style=" color:#800080;">QWidget</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">*</span><span style=" color:#000000;">parent</span><span
style=" color:#000000;">)</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">:</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QWidget</span><span
style=" color:#000000;">(</span><span style=" color:#000000;">parent</span><span
style=" color:#000000;">),</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800000;">ui</span><span
style=" color:#000000;">(</span><span style=" color:#808000;">new</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#800080;">Ui</span><span style=" color:#000000;">::</span><span style=" color:#800080;">Widget</span><span
style=" color:#000000;">)</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800000;">ui</span><span
style=" color:#000000;">-&gt;</span><span style=" color:#000000;">setupUi</span><span
style=" color:#000000;">(</span><span style=" color:#808000;">this</span><span style=" color:#000000;">);</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//先把所有条目设置为可编辑特性,并且显示条目的复选框状态</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">int</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">nCount</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">=</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#800000;">ui</span><span style=" color:#000000;">-&gt;</span><span
style=" color:#800000;">listWidget</span><span style=" color:#000000;">-&gt;</span><span
style=" color:#000000;">count</span><span style=" color:#000000;">();</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">for</span><span
style=" color:#000000;">(</span><span style=" color:#808000;">int</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">i</span><span style=" color:#000000;">=</span><span style=" color:#000080;">0</span><span
style=" color:#000000;">;</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">i</span><span
style=" color:#000000;">&lt;</span><span style=" color:#000000;">nCount</span><span
style=" color:#000000;">;</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">i</span><span
style=" color:#000000;">++)</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QListWidgetItem</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">*</span><span style=" color:#000000;">item</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">=</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#800000;">ui</span><span style=" color:#000000;">-&gt;</span><span
style=" color:#800000;">listWidget</span><span style=" color:#000000;">-&gt;</span><span
style=" color:#000000;">item</span><span style=" color:#000000;">(</span><span style=" color:#000000;">i</span><span
style=" color:#000000;">);</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//启用可编辑特性标志位</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">item</span><span
style=" color:#000000;">-&gt;</span><span style=" color:#000000;">setFlags</span><span
style=" color:#000000;">(</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">(</span><span
style=" color:#000000;">item</span><span style=" color:#000000;">-&gt;</span><span
style=" color:#000000;">flags</span><span style=" color:#000000;">())</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">|</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#800080;">Qt</span><span style=" color:#000000;">::</span><span style=" color:#800080;">ItemIsEditable</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">);</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//显示复选框</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">item</span><span
style=" color:#000000;">-&gt;</span><span style=" color:#000000;">setCheckState</span><span
style=" color:#000000;">(</span><span style=" color:#800080;">Qt</span><span style=" color:#000000;">::</span><span
style=" color:#800080;">Unchecked</span><span style=" color:#000000;">);</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//DOTA最多携带六个装备,有复选框之后,勾选表示携带,不勾选是不携带</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//后面代码检查只能带六个的限制条件</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">}</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//程序运行时新增的装备条目也要开启编辑标志位、复选框,等会实现</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//装备名称可以直接双击修改</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">}</span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#800080;">Widget</span><span style=" color:#000000;">::~</span><span
style=" font-style:italic; color:#000000;">Widget</span><span style=" color:#000000;">()</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">delete</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#800000;">ui</span><span style=" color:#000000;">;</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">}</span></pre>
</div>
头文件包含的图标类 &lt;QIcon&gt;,用于打开新增装备的图标文件。&lt;QFileDialog&gt;
是打开和保存文件时用的文件对话框。&lt;QMessageBox&gt; 用于显示消息框。&lt;QFile&gt;
&lt;QDataStream&gt; 用于保存装备条目文件和加载装备条目文件。<br>
在构造函数里面新增了一段 for
循环代码,先获取列表控件条目的计数,然修改每个条目的特性标志位,开启可编辑特性,然后把复选状态设置为非选中状态,这样会显示出复选框。本例子列表条目大部分的数据都
是条目的通用数据,代码中可编辑特性标志位是属于非通用数据。<br>
开启条目的可编辑特性,是方便用户双击条目修改装备名称,比如大炮是暴雪弩炮的俗称。<br>
显示的复选框,主要是用于显示装备的携带状态,勾选状态是携带的,非勾选状态是不携带的,DOTA 最多可以带 6 个装备,我们在后面代码会检查携带 6
个的数目限制。<br>
我们之前在列表控件预置了 3 个装备,程序运行时还可以选择装备图标文件,添加新的装备,这样列表里的装备可以有很多。<br>
<br>
接着我们来编写条目选中序号变化时调用发的槽函数:<br>
<div class="code"><span style=" color:#008000;">//当前高亮选中的条目序号变化</span>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#808000;">void</span><span style=" color:#c0c0c0;"> </span><span style=" color:#800080;">Widget</span><span
style=" color:#000000;">::</span><span style=" color:#000000;">on_listWidget_currentItemChanged</span><span
style=" color:#000000;">(</span><span style=" color:#800080;">QListWidgetItem</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">*</span><span style=" color:#000000;">current</span><span
style=" color:#000000;">,</span><span style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QListWidgetItem</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">*</span><span style=" color:#000000;">previous</span><span
style=" color:#000000;">)</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">if</span><span
style=" color:#000000;">(</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000080;">NULL</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">==</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">current</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">)</span><span style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//空指针不处理</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">return</span><span
style=" color:#000000;">;</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">}</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//获取新选中条目的工具提示信息显示到单行编辑器</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QString</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">strToolTip</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">=</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">current</span><span style=" color:#000000;">-&gt;</span><span
style=" color:#000000;">toolTip</span><span style=" color:#000000;">();</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800000;">ui</span><span
style=" color:#000000;">-&gt;</span><span style=" color:#800000;">lineEditToolTip</span><span
style=" color:#000000;">-&gt;</span><span style=" color:#000000;">setText</span><span
style=" color:#000000;">(</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">strToolTip</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">);</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//在</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">"编辑工具提示"</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">按钮对应的槽函数实现修改条目的工具提示</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">}</span></pre>
</div>
当前选中条目的序号变化时,该槽函数第一个参数是现在新选中的条目指针,第二个参数是旧的选中条目指针。注意指针有可能是
NULL,如果要用到哪个指针,一定要判断指针是否为空值。这个槽函数主要是根据高亮选中条目的变化,在单行编辑器里同步显示当前条目的工具提示信息。<br>
与这个条目选中变化槽函数紧密相关的是 "编辑工具提示" 按钮对应的槽函数,我们把这个按钮槽函数提到前面来讲解:<br>
<div class="code"><span style=" color:#008000;">//修改条目的工具提示信息,相当于修改装备描述</span>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#808000;">void</span><span style=" color:#c0c0c0;"> </span><span style=" color:#800080;">Widget</span><span
style=" color:#000000;">::</span><span style=" color:#000000;">on_pushButtonEditToolTip_clicked</span><span
style=" color:#000000;">()</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//新的工具提示信息</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QString</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">strNew</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">=</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#800000;">ui</span><span style=" color:#000000;">-&gt;</span><span
style=" color:#800000;">lineEditToolTip</span><span style=" color:#000000;">-&gt;</span><span
style=" color:#000000;">text</span><span style=" color:#000000;">();</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//获取当前选中条目</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QListWidgetItem</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">*</span><span style=" color:#000000;">curItem</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">=</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#800000;">ui</span><span style=" color:#000000;">-&gt;</span><span
style=" color:#800000;">listWidget</span><span style=" color:#000000;">-&gt;</span><span
style=" color:#000000;">currentItem</span><span style=" color:#000000;">();</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">if</span><span
style=" color:#000000;">(</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">curItem</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">!=</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000080;">NULL</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">)</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//检查是否为空指针</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//设置新的工具提示信息</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">curItem</span><span
style=" color:#000000;">-&gt;</span><span style=" color:#000000;">setToolTip</span><span
style=" color:#000000;">(</span><span style=" color:#000000;">strNew</span><span
style=" color:#000000;">);</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">}</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">}</span></pre>
</div>
当用户点击 "编辑工具提示" 按钮时,这个槽函数会先获取单行编辑器的文本,然后获取当前高亮选中的条目 curItem ,判断 curItem
指针非空之后,将新的工具提示信息设置给该条目。凡是涉及到指针的,都要注意判断指针是否为 NULL。<br>
涉及到工具提示信息的编辑的,就是上面两个槽函数。<br>
<br>
然后我们来看看装备条目复选框的勾选检查,我们要保证勾选的装备不超过 6
个。列表控件的条目内部数据发生变化时,无论是文本、图标、工具提示、复选状态等等,都只触发列表控件的
itemChanged(QListWidgetItem *) 信号,所以我们要自己筛选需要的复选框状态信息:<br>
<div class="code"><span style=" color:#008000;">//限定</span><span style=" color:#c0c0c0;">
</span><span style=" color:#008000;">DOTA</span><span style=" color:#c0c0c0;">
</span><span style=" color:#008000;">装备只能携带</span><span style=" color:#c0c0c0;">
</span><span style=" color:#008000;">6</span><span style=" color:#c0c0c0;">
</span><span style=" color:#008000;"></span>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#808000;">void</span><span style=" color:#c0c0c0;"> </span><span style=" color:#800080;">Widget</span><span
style=" color:#000000;">::</span><span style=" color:#000000;">on_listWidget_itemChanged</span><span
style=" color:#000000;">(</span><span style=" color:#800080;">QListWidgetItem</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">*</span><span style=" color:#000000;">item</span><span
style=" color:#000000;">)</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//空指针不处理</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">if</span><span
style=" color:#000000;">(</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000080;">NULL</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">==</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">item</span><span style=" color:#000000;">)</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">return</span><span
style=" color:#000000;">;</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">}</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//实际存在的条目变化</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">if</span><span
style=" color:#000000;">(</span><span style=" color:#000000;">item</span><span style=" color:#000000;">-&gt;</span><span
style=" color:#000000;">checkState</span><span style=" color:#000000;">()</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">!=</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#800080;">Qt</span><span style=" color:#000000;">::</span><span style=" color:#800080;">Checked</span><span
style=" color:#000000;">)</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//复选框没选中,没携带的不检查</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">return</span><span
style=" color:#000000;">;</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">}</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//如果复选框处于选中状态,检查装备携带是否超过</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">6</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;"></span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">int</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">nCount</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">=</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#800000;">ui</span><span style=" color:#000000;">-&gt;</span><span
style=" color:#800000;">listWidget</span><span style=" color:#000000;">-&gt;</span><span
style=" color:#000000;">count</span><span style=" color:#000000;">();</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">int</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">nUsingItemsCount</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">=</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000080;">0</span><span style=" color:#000000;">;</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">for</span><span
style=" color:#000000;">(</span><span style=" color:#808000;">int</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">i</span><span style=" color:#000000;">=</span><span style=" color:#000080;">0</span><span
style=" color:#000000;">;</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">i</span><span
style=" color:#000000;">&lt;</span><span style=" color:#000000;">nCount</span><span
style=" color:#000000;">;</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">i</span><span
style=" color:#000000;">++)</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QListWidgetItem</span><span
style=" color:#000000;">*</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">theItem</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">=</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#800000;">ui</span><span style=" color:#000000;">-&gt;</span><span
style=" color:#800000;">listWidget</span><span style=" color:#000000;">-&gt;</span><span
style=" color:#000000;">item</span><span style=" color:#000000;">(</span><span style=" color:#000000;">i</span><span
style=" color:#000000;">);</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">if</span><span
style=" color:#000000;">(</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">theItem</span><span
style=" color:#000000;">-&gt;</span><span style=" color:#000000;">checkState</span><span
style=" color:#000000;">()</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">==</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">Qt</span><span style=" color:#000000;">::</span><span
style=" color:#800080;">Checked</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">)</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//携带数加一</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">nUsingItemsCount</span><span
style=" color:#000000;">++;</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">}</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">}</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//判断是否超过</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">6</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;"></span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">if</span><span
style=" color:#000000;">(</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">nUsingItemsCount</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">&gt;</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000080;">6</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">)</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QMessageBox</span><span
style=" color:#000000;">::</span><span style=" color:#000000;">warning</span><span
style=" color:#000000;">(</span><span style=" color:#808000;">this</span><span style=" color:#000000;">,</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">tr</span><span style=" color:#000000;">(</span><span
style=" color:#008000;">"携带数目检查"</span><span style=" color:#000000;">),</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">tr</span><span style=" color:#000000;">(</span><span
style=" color:#008000;">"DOTA</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;">装备最多带</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;">6</span><span style=" color:#c0c0c0;"> </span><span style=" color:#008000;">个!"</span><span
style=" color:#000000;">));</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//把当前变化的</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">item</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;">设置为非选中状态</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">item</span><span
style=" color:#000000;">-&gt;</span><span style=" color:#000000;">setCheckState</span><span
style=" color:#000000;">(</span><span style=" color:#c0c0c0;"> </span><span style=" color:#800080;">Qt</span><span
style=" color:#000000;">::</span><span style=" color:#800080;">Unchecked</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">);</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">}</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">}</span></pre>
</div>
该槽函数先判断参数里的 item 是否为空指针,如果为空指针就不处理。<br>
接着判断 item 条目里的复选框状态,如果处于非选中状态,说明没携带该装备,就不用后续的判断,直接返回。<br>
如果携带了该装备,那我们要枚举所有的列表条目,如果列表条目复选框处于勾选状态,那就增加携带计数 nUsingItemsCount。<br>
统计好 nUsingItemsCount 之后,判断携带数量是否大于 6,大于 6 就把 item 条目的勾选状态取消,回到不携带的状态。<br>
<br>
这个函数工作原理比较简单:如果用户取消勾选装备,那么不用判断,如果用户选中携带装备,那么每次携带都会让上面槽函数执行一次检查,直到超过 6
个就不会再携带超额的装备了。<br>
<br>
因为我们例子初始时只有 3 个装备,当然不够,我们下面来看看添加新装备的槽函数:<br>
<div class="code"><span style=" color:#008000;">//用户选择装备图标文件,添加新装备条目</span>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#808000;">void</span><span style=" color:#c0c0c0;"> </span><span style=" color:#800080;">Widget</span><span
style=" color:#000000;">::</span><span style=" color:#000000;">on_pushButtonAdd_clicked</span><span
style=" color:#000000;">()</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//获取新装备图标的文件路径</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QString</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">strItemFileName</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">=</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#800080;">QFileDialog</span><span style=" color:#000000;">::</span><span
style=" color:#000000;">getOpenFileName</span><span style=" color:#000000;">(</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">this</span><span
style=" color:#000000;">,</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">tr</span><span
style=" color:#000000;">(</span><span style=" color:#008000;">"选择装备图标文件"</span><span
style=" color:#000000;">),</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">tr</span><span
style=" color:#000000;">(</span><span style=" color:#008000;">"."</span><span style=" color:#000000;">),</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">tr</span><span
style=" color:#000000;">(</span><span style=" color:#008000;">"Image</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">files(*.jpg</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">*.png</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">*.bmp);;All</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">files(*)"</span><span
style=" color:#000000;">)</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">);</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">if</span><span
style=" color:#000000;">(</span><span style=" color:#000000;">strItemFileName</span><span
style=" color:#000000;">.</span><span style=" color:#000000;">isEmpty</span><span
style=" color:#000000;">())</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//没有文件名,返回</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">return</span><span
style=" color:#000000;">;</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">}</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//打开装备图标文件</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QIcon</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">iconNew</span><span
style=" color:#000000;">(</span><span style=" color:#000000;">strItemFileName</span><span
style=" color:#000000;">);</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//新建条目,文本初始是默认的,自动添加到列表控件</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QListWidgetItem</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">*</span><span style=" color:#000000;">itemNew</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">=</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#808000;">new</span><span style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QListWidgetItem</span><span
style=" color:#000000;">(</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">iconNew</span><span
style=" color:#000000;">,</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">tr</span><span
style=" color:#000000;">(</span><span style=" color:#008000;">"新装备名称"</span><span
style=" color:#000000;">),</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800000;">ui</span><span
style=" color:#000000;">-&gt;</span><span style=" color:#800000;">listWidget</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">);</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//开启条目编辑特性</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">itemNew</span><span
style=" color:#000000;">-&gt;</span><span style=" color:#000000;">setFlags</span><span
style=" color:#000000;">(</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">(</span><span
style=" color:#000000;">itemNew</span><span style=" color:#000000;">-&gt;</span><span
style=" color:#000000;">flags</span><span style=" color:#000000;">())</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">|</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#800080;">Qt</span><span style=" color:#000000;">::</span><span style=" color:#800080;">ItemIsEditable</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">);</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//显示复选框</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">itemNew</span><span
style=" color:#000000;">-&gt;</span><span style=" color:#000000;">setCheckState</span><span
style=" color:#000000;">(</span><span style=" color:#c0c0c0;"> </span><span style=" color:#800080;">Qt</span><span
style=" color:#000000;">::</span><span style=" color:#800080;">Unchecked</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">);</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//设置新的当前条目</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800000;">ui</span><span
style=" color:#000000;">-&gt;</span><span style=" color:#800000;">listWidget</span><span
style=" color:#000000;">-&gt;</span><span style=" color:#000000;">setCurrentItem</span><span
style=" color:#000000;">(</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">itemNew</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">);</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//新增条目自动启用编辑功能,让用户可以立即修改新装备名称</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800000;">ui</span><span
style=" color:#000000;">-&gt;</span><span style=" color:#800000;">listWidget</span><span
style=" color:#000000;">-&gt;</span><span style=" color:#000000;">editItem</span><span
style=" color:#000000;">(</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">itemNew</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">);</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">}</span></pre>
</div>
该槽函数先获取要打开的图标文件名称 strItemFileName,并判断是否非空。<br>
然后根据文件名定义图标对象 iconNew,并新建一个列表条目,新增条目初始时文本都是
"新装备名称",条目图标就是刚定义的图标对象,而且条目会自动添加到列表控件;<br>
接着开启该条目的可编辑标志位,并设置条目的复选状态,显示条目配套的复选框;<br>
最后将列表当前高亮选中的条目设置为刚刚新增的条目,并且调用 editItem() 函数,自动进入该条目文本的编辑框,方便用户立即修改这个新装备名称。<br>
<br>
与增加装备相反的是删除条目的槽函数:<br>
<div class="code"><span style=" color:#008000;">//删除当前选中的装备条目</span>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#808000;">void</span><span style=" color:#c0c0c0;"> </span><span style=" color:#800080;">Widget</span><span
style=" color:#000000;">::</span><span style=" color:#000000;">on_pushButtonDel_clicked</span><span
style=" color:#000000;">()</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">int</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">nCurRow</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">=</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#800000;">ui</span><span style=" color:#000000;">-&gt;</span><span
style=" color:#800000;">listWidget</span><span style=" color:#000000;">-&gt;</span><span
style=" color:#000000;">currentRow</span><span style=" color:#000000;">();</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">if</span><span
style=" color:#000000;">(</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">nCurRow</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">&lt;</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000080;">0</span><span style=" color:#000000;">)</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//没有选中的条目</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">return</span><span
style=" color:#000000;">;</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">}</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//从列表控制移除选中的条目</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QListWidgetItem</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">*</span><span style=" color:#000000;">itemDel</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">=</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#800000;">ui</span><span style=" color:#000000;">-&gt;</span><span
style=" color:#800000;">listWidget</span><span style=" color:#000000;">-&gt;</span><span
style=" color:#000000;">takeItem</span><span style=" color:#000000;">(</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">nCurRow</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">);</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//彻底删除移除的条目</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">delete</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">itemDel</span><span
style=" color:#000000;">;</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">itemDel</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">=</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000080;">NULL</span><span style=" color:#000000;">;</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">}</span></pre>
</div>
删除条目的槽函数先获取当前选中条目的行号,判断行号是否合法;对于合法的行号,使用 takeItem()
函数从列表控件移除该条目,移除条目并不是从内存彻底删除,要彻底删除条目还得手动 delete 已经移除的条目。<br>
注意列表控件的 takeItem() 函数只是根据行号解除该行条目的隶属关系,而不会从内存消掉该条目内容,因此需要手动 delete。<br>
<br>
然后我们来看看列表控件切换显示模式的槽函数:<br>
<div class="code"><span style=" color:#008000;">//切换小图标文本模式和大图标模式</span>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#808000;">void</span><span style=" color:#c0c0c0;"> </span><span style=" color:#800080;">Widget</span><span
style=" color:#000000;">::</span><span style=" color:#000000;">on_pushButtonViewMode_clicked</span><span
style=" color:#000000;">()</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QListView</span><span
style=" color:#000000;">::</span><span style=" color:#800080;">ViewMode</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">vm</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">=</span><span style=" color:#c0c0c0;"> </span><span style=" color:#800000;">ui</span><span
style=" color:#000000;">-&gt;</span><span style=" color:#800000;">listWidget</span><span
style=" color:#000000;">-&gt;</span><span style=" color:#000000;">viewMode</span><span
style=" color:#000000;">();</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">if</span><span
style=" color:#000000;">(</span><span style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QListView</span><span
style=" color:#000000;">::</span><span style=" color:#800080;">ListMode</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">==</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">vm</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">)</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//切换到大图标显示,大图标可以拖动,但是不会改变内部真实的条目序号</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800000;">ui</span><span
style=" color:#000000;">-&gt;</span><span style=" color:#800000;">listWidget</span><span
style=" color:#000000;">-&gt;</span><span style=" color:#000000;">setViewMode</span><span
style=" color:#000000;">(</span><span style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QListView</span><span
style=" color:#000000;">::</span><span style=" color:#800080;">IconMode</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">);</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">}</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">else</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//切换到小图标文字显示,条目不可拖动</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800000;">ui</span><span
style=" color:#000000;">-&gt;</span><span style=" color:#800000;">listWidget</span><span
style=" color:#000000;">-&gt;</span><span style=" color:#000000;">setViewMode</span><span
style=" color:#000000;">(</span><span style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QListView</span><span
style=" color:#000000;">::</span><span style=" color:#800080;">ListMode</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">);</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">}</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">}</span></pre>
</div>
之前没介绍列表空间的显示模式属性 viewMode,这个属性是从基类 QListView 继承来的,显示模式目前只有两种:<br>
QListView::ListMode,默认值是这个小图标文本列表模式,重点是显示条目的文本,所有条目是静态的,不可拖动;<br>
QListView::IconMode,大图标显示模式,重点显示大图标,大图标可以拖动位置,但拖动位置不改变条目实际的排序。<br>
条目是否可以拖动的特性是可以通过修改 movement 属性实现,这些等到讲解基类 QListView 再详细说,这里只是点一下。<br>
<br>
最后我们来看看 "保存" 和 "加载" 两个按钮的槽函数,这两个槽函数稍微有点复杂,先看 "保存" 按钮的槽函数:<br>
<div class="code"><span style=" color:#008000;">//保存所有条目到文件</span>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#808000;">void</span><span style=" color:#c0c0c0;"> </span><span style=" color:#800080;">Widget</span><span
style=" color:#000000;">::</span><span style=" color:#000000;">on_pushButtonSave_clicked</span><span
style=" color:#000000;">()</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//获取保存文件名</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QString</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">strSaveName</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">=</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#800080;">QFileDialog</span><span style=" color:#000000;">::</span><span
style=" color:#000000;">getSaveFileName</span><span style=" color:#000000;">(</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">this</span><span
style=" color:#000000;">,</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">tr</span><span
style=" color:#000000;">(</span><span style=" color:#008000;">"保存items文件"</span><span
style=" color:#000000;">),</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">tr</span><span
style=" color:#000000;">(</span><span style=" color:#008000;">"."</span><span style=" color:#000000;">),</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">tr</span><span
style=" color:#000000;">(</span><span style=" color:#008000;">"Items</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">files(*.items)"</span><span
style=" color:#000000;">));</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//判断文件名</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">if</span><span
style=" color:#000000;">(</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">strSaveName</span><span
style=" color:#000000;">.</span><span style=" color:#000000;">isEmpty</span><span
style=" color:#000000;">()</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">)</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">return</span><span
style=" color:#000000;">;</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">}</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//打开要写入的文件</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QFile</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">fileSave</span><span
style=" color:#000000;">(</span><span style=" color:#000000;">strSaveName</span><span
style=" color:#000000;">);</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">if</span><span
style=" color:#000000;">(</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">!</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">fileSave</span><span
style=" color:#000000;">.</span><span style=" font-style:italic; color:#000000;">open</span><span
style=" color:#000000;">(</span><span style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QIODevice</span><span
style=" color:#000000;">::</span><span style=" color:#800080;">WriteOnly</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">))</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//无法打开要写入的文件</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QMessageBox</span><span
style=" color:#000000;">::</span><span style=" color:#000000;">warning</span><span
style=" color:#000000;">(</span><span style=" color:#808000;">this</span><span style=" color:#000000;">,</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">tr</span><span style=" color:#000000;">(</span><span
style=" color:#008000;">"打开写入文件"</span><span style=" color:#000000;">),</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">tr</span><span
style=" color:#000000;">(</span><span style=" color:#008000;">"打开要写入的文件失败,请检查文件名和是否具有写入权限!"</span><span
style=" color:#000000;">));</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">return</span><span
style=" color:#000000;">;</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">}</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//创建数据流</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QDataStream</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">dsOut</span><span
style=" color:#000000;">(&amp;</span><span style=" color:#000000;">fileSave</span><span
style=" color:#000000;">);</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//先写入列表条目计数</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">qint32</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">nCount</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">=</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#800000;">ui</span><span style=" color:#000000;">-&gt;</span><span
style=" color:#800000;">listWidget</span><span style=" color:#000000;">-&gt;</span><span
style=" color:#000000;">count</span><span style=" color:#000000;">();</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">dsOut</span><span
style=" color:#000000;">&lt;&lt;</span><span style=" color:#000000;">nCount</span><span
style=" color:#000000;">;</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//逐个写入条目</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">for</span><span
style=" color:#000000;">(</span><span style=" color:#800080;">qint32</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">i</span><span style=" color:#000000;">=</span><span
style=" color:#000080;">0</span><span style=" color:#000000;">;</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">i</span><span style=" color:#000000;">&lt;</span><span style=" color:#000000;">nCount</span><span
style=" color:#000000;">;</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">i</span><span
style=" color:#000000;">++)</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QListWidgetItem</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">*</span><span style=" color:#000000;">theItem</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">=</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#800000;">ui</span><span style=" color:#000000;">-&gt;</span><span
style=" color:#800000;">listWidget</span><span style=" color:#000000;">-&gt;</span><span
style=" color:#000000;">item</span><span style=" color:#000000;">(</span><span style=" color:#000000;">i</span><span
style=" color:#000000;">);</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">dsOut</span><span
style=" color:#000000;">&lt;&lt;</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">*</span><span style=" color:#000000;">theItem</span><span
style=" color:#000000;">;</span><span style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//把条目对象写入数据流,不是写指针数值</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//数据流仅写入条目通用数据,条目的非通用数据不写入,比如条目的标志位不写</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">}</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//写入完毕</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">}</span></pre>
</div>
我们保存的文件是自定义的数据流文件,先写入条目计数,然后依次写入各个条目,文件扩展名为 *.items。<br>
该槽函数先获取要保存的文件名,并判断文件名非空。<br>
然后根据文件名定义文件对象 fileSave,以只写模式打开文件,如果打开出错就提示并返回。<br>
如果文件打开成功,就根据文件对象定义数据流对象 dsOut;<br>
获取列表控件的条目计数 nCount,写入到数据流;<br>
然后枚举各个条目,将所有条目对象都写入数据流。<br>
<br>
注意是将条目对象 *theItem 写入数据流,theItem
是指针,不能直接把指针值写入数据流,指针值本身是没用的,要存储条目对象的本体。数据流会自动把条目的通用数据(包括文本、图标、工具提示、复选框状态等等一大堆)存入
文件,但是非通用的数据,比如可编辑特性标志,是不写文件的。 QListWidgetItem::​flags() 的标志位都不会写入文件,等会加载
*.items 文件的时候,我们需要自己动手修改标志位。<br>
<br>
再来看看 "加载" 按钮对应的槽函数:<br>
<div class="code"><span style=" color:#008000;">//加载之前保存的文件</span>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#808000;">void</span><span style=" color:#c0c0c0;"> </span><span style=" color:#800080;">Widget</span><span
style=" color:#000000;">::</span><span style=" color:#000000;">on_pushButtonLoad_clicked</span><span
style=" color:#000000;">()</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//获取要加载的文件名</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QString</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">strOpenName</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">=</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#800080;">QFileDialog</span><span style=" color:#000000;">::</span><span
style=" color:#000000;">getOpenFileName</span><span style=" color:#000000;">(</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">this</span><span
style=" color:#000000;">,</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">tr</span><span
style=" color:#000000;">(</span><span style=" color:#008000;">"打开items文件"</span><span
style=" color:#000000;">),</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">tr</span><span
style=" color:#000000;">(</span><span style=" color:#008000;">"."</span><span style=" color:#000000;">),</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">tr</span><span
style=" color:#000000;">(</span><span style=" color:#008000;">"Items</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">files(*.items)"</span><span
style=" color:#000000;">));</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//判断文件名</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">if</span><span
style=" color:#000000;">(</span><span style=" color:#000000;">strOpenName</span><span
style=" color:#000000;">.</span><span style=" color:#000000;">isEmpty</span><span
style=" color:#000000;">())</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">return</span><span
style=" color:#000000;">;</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">}</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//打开文件</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QFile</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">fileOpen</span><span
style=" color:#000000;">(</span><span style=" color:#000000;">strOpenName</span><span
style=" color:#000000;">);</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">if</span><span
style=" color:#000000;">(</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">!</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">fileOpen</span><span
style=" color:#000000;">.</span><span style=" font-style:italic; color:#000000;">open</span><span
style=" color:#000000;">(</span><span style=" color:#800080;">QIODevice</span><span
style=" color:#000000;">::</span><span style=" color:#800080;">ReadOnly</span><span
style=" color:#000000;">))</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//打开出错</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QMessageBox</span><span
style=" color:#000000;">::</span><span style=" color:#000000;">warning</span><span
style=" color:#000000;">(</span><span style=" color:#808000;">this</span><span style=" color:#000000;">,</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">tr</span><span style=" color:#000000;">(</span><span
style=" color:#008000;">"打开文件"</span><span style=" color:#000000;">),</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">tr</span><span
style=" color:#000000;">(</span><span style=" color:#008000;">"打开指定文件失败,请检查文件是否存在和读取权限!"</span><span
style=" color:#000000;">));</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">return</span><span
style=" color:#000000;">;</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">}</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//创建读取数据流</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QDataStream</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">dsIn</span><span style=" color:#000000;">(&amp;</span><span
style=" color:#000000;">fileOpen</span><span style=" color:#000000;">);</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//读取条目计数</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">qint32</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">nCount</span><span
style=" color:#000000;">;</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">dsIn</span><span
style=" color:#000000;">&gt;&gt;</span><span style=" color:#000000;">nCount</span><span
style=" color:#000000;">;</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//判断计数数值</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">if</span><span
style=" color:#000000;">(</span><span style=" color:#000000;">nCount</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">&lt;=</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000080;">0</span><span style=" color:#000000;">)</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QMessageBox</span><span
style=" color:#000000;">::</span><span style=" color:#000000;">warning</span><span
style=" color:#000000;">(</span><span style=" color:#808000;">this</span><span style=" color:#000000;">,</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">tr</span><span style=" color:#000000;">(</span><span
style=" color:#008000;">"文件加载"</span><span style=" color:#000000;">),</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">tr</span><span
style=" color:#000000;">(</span><span style=" color:#008000;">"文件中无条目数据可以加载!"</span><span
style=" color:#000000;">));</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">return</span><span
style=" color:#000000;">;</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">}</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//新建各个条目,并加载文件中的条目数据</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">for</span><span
style=" color:#000000;">(</span><span style=" color:#800080;">qint32</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">i</span><span style=" color:#000000;">=</span><span
style=" color:#000080;">0</span><span style=" color:#000000;">;</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">i</span><span style=" color:#000000;">&lt;</span><span style=" color:#000000;">nCount</span><span
style=" color:#000000;">;</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">i</span><span
style=" color:#000000;">++)</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//新建条目,条目自动添加到列表控件</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QListWidgetItem</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">*</span><span style=" color:#000000;">theItem</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">=</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#808000;">new</span><span style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QListWidgetItem</span><span
style=" color:#000000;">(</span><span style=" color:#800000;">ui</span><span style=" color:#000000;">-&gt;</span><span
style=" color:#800000;">listWidget</span><span style=" color:#000000;">);</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//加载条目通用数据,文字、图标、工具提示、复选状态等是通用数据,在数据流里面有保存</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">dsIn</span><span
style=" color:#000000;">&gt;&gt;</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">*</span><span style=" color:#000000;">theItem</span><span
style=" color:#000000;">;</span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//条目的非通用数据是不保存到数据流的</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//这里需要手动把条目设置为可编辑的特性标志位</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">theItem</span><span
style=" color:#000000;">-&gt;</span><span style=" color:#000000;">setFlags</span><span
style=" color:#000000;">(</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">(</span><span
style=" color:#000000;">theItem</span><span style=" color:#000000;">-&gt;</span><span
style=" color:#000000;">flags</span><span style=" color:#000000;">())</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">|</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#800080;">Qt</span><span style=" color:#000000;">::</span><span style=" color:#800080;">ItemIsEditable</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">);</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">}</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//加载完毕</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">}</span></pre>
</div>
这个槽函数先获取要加载的文件名,并检查文件名是否非空。<br>
然后根据文件名定义文件对象 fileOpen,并用只读模式打开,如果打开失败就报错并返回。<br>
如果文件打开正确,就定义数据流对象 dsIn;<br>
先从数据流读取条目计数 nCount,判断 nCount 数值,如果不是正数,就提示没有条目数据,直接返回。<br>
如果有正确的条目计数,那就用 for 循环逐个新建列表条目对象,新建的对象指针为 theItem ;<br>
把数据流中的条目数据读取到对象本体 *theItem;<br>
最后要注意的就是条目的非通用数据是不保存的,标志位需要自己手动设置,我们加了一句条目的 setFlags() 函数调用,为条目设置为可编辑的特性标志位。<br>
<br>
这个游戏装备列表示例的代码就是上面那些,我们现在生成运行例子看看:<br>
<center><img src="images/ch08/ch08-01-23.png" alt="run1"></center>
当鼠标悬停在第三个大炮(暴雪弩炮)的图标上时,可以看到工具提示信息,有图有真相,就是装备的描述信息。<br>
我们可以再添加多个装备条目,并测试 6 个装备限制条件:<br>
<center><img src="images/ch08/ch08-01-24.png" alt="run2"></center>
当勾选第 7 个装备的时候,弹出消息框提示只能带 6 个,点击消息框 OK 按钮之后,第 7 个装备会自动取消勾选,回到只勾选 6
个的状态。示例程序其他功能这里就不截图了,这个例子的代码较多,涉及的知识点也比较多,读者最好把每个槽函数的代码都吃透,并测试每个槽函数代码在程序运行时的实际效
果。<br>
<br>
<div class="os2">8.1.4 歌曲列表示例</div>
<br>
上一小节涉及列表控件大部分的功能,我们在本小节再学习一个歌曲列表示例,歌曲列表可以一次添加多个音乐文件,支持同时选中多个音乐条目,也能同时删除多个音乐条
目。另外还能根据模板字符串查找匹配的条目进行高亮显示,歌曲列表还可以导出为 *.m3u 播放列表文件格式。 *.m3u 本质就是文本文件,最简单的
*.m3u 播放列表第一行是文本 #EXTM3U ,后面每行放一个音乐文件名,例如:<br>
<div class="code">#EXTM3U<br>
D:/我的文档/My Music/仙剑/蝶恋.mp3<br>
D:/我的文档/My Music/仙剑/六月的雨.mp3<br>
D:/我的文档/My Music/仙剑/沙破狼.mp3<br>
D:/我的文档/My Music/仙剑/逍遥叹.mp3<br>
D:/我的文档/My Music/仙剑/一直很安静.mp3</div>
下面开始这个例子的学习,打开 QtCreator,新建一个 Qt Widgets Application 项目,在新建项目的向导里填写:<br>
①项目名称 musiclist,创建路径 D:\QtProjects\ch08,点击下一步;<br>
②套件选择里面选择全部套件,点击下一步;<br>
③基类选择 QWidget,点击下一步;<br>
④项目管理不修改,点击完成。<br>
我们打开 widget.ui 界面文件,按照下图拖入控件:<br>
<center><img src="images/ch08/ch08-01-25.png" alt="ui" width="800"></center>
界面分成左右两个大部分:<br>
左边有列表控件和单行编辑器,列表控件对象名 listWidget;单行编辑控件对象名 lineEditTemplate;两个空间按照垂直布局器排布。<br>
右边是四个按钮和两个复选框,第一个按钮文本为 "添加",对象名 pushButtonAdd;第二个按钮文本为 "删除",对象名
pushButtonDel;第三个按钮文本为 "导出m3u",对象名 pushButtonExportM3U;第一个复选框文本为 "自动排序",对象名
checkBoxAutoSort;第二个复选框文本为 "逆序排列",对象名
checkBoxReverse;第二个复选框与最后一个按钮之间有垂直空白条;最后一个按钮文本为 "查找",对象名
pushButtonFind;右边的控件也按照垂直布局排布。<br>
界面的主布局是按照水平布局器排布。<br>
<br>
这里介绍一下按钮和复选框的用途,"添加" 按钮支持把多个音乐文件名添加到列表控件,"删除"按钮支持从列表控件删除多个条目;"导出m3u"
按钮是把当前列表控件的条目导出为播放列表文件 *.m3u ;勾选 "自动排序"
复选框之后,列表控件自动对新增的音乐文件名进行排序,音乐文件名的正序或逆序排列由 "逆序排列" 复选框的状态指定;"查找"
按钮是根据单行编辑器的模板字符串,查找哪些条目包含该模板字符串,查找到的条目都会高亮显示。<br>
<br>
我们现在为界面的四个按钮和两个复选框添加槽函数,首先为四个按钮添加 clicked() 信号对应的槽函数:<br>
<center><img src="images/ch08/ch08-01-26.png" alt="slot1-4"></center>
然后为两个复选框都添加 clicked(bool) 信号对应的槽函数:<br>
<center><img src="images/ch08/ch08-01-26.png" alt="slot5-6"></center>
添加好共 6 个槽函数之后,保存界面文件,关闭界面文件,回到 QtCreator 代码编辑模式,开始代码的编写。<br>
<br>
先来看看头文件 widget.h 的代码,头文件代码不需要手动修改,都是自动生成的:<br>
<div class="code"><span style=" color:#000080;">#ifndef</span><span style=" color:#c0c0c0;">
</span>WIDGET_H
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000080;">#define</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000080;">WIDGET_H</span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000080;">#include</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;">&lt;QWidget&gt;</span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#808000;">namespace</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#800080;">Ui</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#808000;">class</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#800080;">Widget</span><span style=" color:#000000;">;</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">}</span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#808000;">class</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#800080;">Widget</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">:</span><span style=" color:#c0c0c0;"> </span><span style=" color:#808000;">public</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QWidget</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000080;">Q_OBJECT</span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#808000;">public</span><span style=" color:#000000;">:</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">explicit</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">Widget</span><span
style=" color:#000000;">(</span><span style=" color:#800080;">QWidget</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">*</span>parent<span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">=</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000080;">0</span><span style=" color:#000000;">);</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">~</span><span style=" font-style:italic; color:#000000;">Widget</span><span
style=" color:#000000;">();</span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#808000;">private</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#808000;">slots</span><span style=" color:#000000;">:</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">void</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">on_pushButtonAdd_clicked</span><span
style=" color:#000000;">();</span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">void</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">on_pushButtonDel_clicked</span><span
style=" color:#000000;">();</span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">void</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">on_pushButtonExportM3U_clicked</span><span
style=" color:#000000;">();</span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">void</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">on_pushButtonFind_clicked</span><span
style=" color:#000000;">();</span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">void</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">on_checkBoxAutoSort_clicked</span><span
style=" color:#000000;">(</span><span style=" color:#808000;">bool</span><span style=" color:#c0c0c0;"> </span>checked<span
style=" color:#000000;">);</span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">void</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">on_checkBoxReverse_clicked</span><span
style=" color:#000000;">(</span><span style=" color:#808000;">bool</span><span style=" color:#c0c0c0;"> </span>checked<span
style=" color:#000000;">);</span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#808000;">private</span><span style=" color:#000000;">:</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">Ui</span><span
style=" color:#000000;">::</span><span style=" color:#800080;">Widget</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">*</span><span style=" color:#800000;">ui</span><span
style=" color:#000000;">;</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">};</span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000080;">#endif</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;">//</span><span style=" color:#c0c0c0;"> </span><span style=" color:#008000;">WIDGET_H</span></pre>
</div>
<br>
我们现在打开源代码文件 widget.cpp ,添加实际的功能代码,首先是头文件包含和构造函数:<br>
<div class="code"><span style=" color:#000080;">#include</span><span style=" color:#c0c0c0;">
</span><span style=" color:#008000;">"widget.h"</span>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000080;">#include</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;">"ui_widget.h"</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000080;">#include</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;">&lt;QDebug&gt;</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000080;">#include</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;">&lt;QMessageBox&gt;</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;">//消息框</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000080;">#include</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;">&lt;QListWidget&gt;</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;">//列表控件</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000080;">#include</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;">&lt;QListWidgetItem&gt;</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;">//列表控件条目</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000080;">#include</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;">&lt;QFileDialog&gt;</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;">//文件对话框</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000080;">#include</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;">&lt;QFileInfo&gt;</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;">//查询文件信息</span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#800080;">Widget</span><span style=" color:#000000;">::</span><span
style=" color:#000000;">Widget</span><span style=" color:#000000;">(</span><span
style=" color:#800080;">QWidget</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">*</span><span style=" color:#000000;">parent</span><span
style=" color:#000000;">)</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">:</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QWidget</span><span
style=" color:#000000;">(</span><span style=" color:#000000;">parent</span><span
style=" color:#000000;">),</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800000;">ui</span><span
style=" color:#000000;">(</span><span style=" color:#808000;">new</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#800080;">Ui</span><span style=" color:#000000;">::</span><span style=" color:#800080;">Widget</span><span
style=" color:#000000;">)</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800000;">ui</span><span
style=" color:#000000;">-&gt;</span><span style=" color:#000000;">setupUi</span><span
style=" color:#000000;">(</span><span style=" color:#808000;">this</span><span style=" color:#000000;">);</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//开启列表控件多选模式</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800000;">ui</span><span
style=" color:#000000;">-&gt;</span><span style=" color:#800000;">listWidget</span><span
style=" color:#000000;">-&gt;</span><span style=" color:#000000;">setSelectionMode</span><span
style=" color:#000000;">(</span><span style=" color:#800080;">QAbstractItemView</span><span
style=" color:#000000;">::</span><span style=" color:#800080;">ExtendedSelection</span><span
style=" color:#000000;">);</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//开启自动排序</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800000;">ui</span><span
style=" color:#000000;">-&gt;</span><span style=" color:#800000;">checkBoxAutoSort</span><span
style=" color:#000000;">-&gt;</span><span style=" color:#000000;">setCheckState</span><span
style=" color:#000000;">(</span><span style=" color:#800080;">Qt</span><span style=" color:#000000;">::</span><span
style=" color:#800080;">Checked</span><span style=" color:#000000;">);</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">}</span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#800080;">Widget</span><span style=" color:#000000;">::~</span><span
style=" font-style:italic; color:#000000;">Widget</span><span style=" color:#000000;">()</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">delete</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#800000;">ui</span><span style=" color:#000000;">;</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">}</span></pre>
</div>
包含的头文件在上一个例子基本都见过了,不重复讲了,最后一个头文件 &lt;QFileInfo&gt; 用于根据路径文件名提取文件的基本名,显示到列表条
目。<br>
在构造函数里,主要添加了两句代码:<br>
新增的第一句调用列表控件的 setSelectionMode(QAbstractItemView::ExtendedSelection)
函数,设置多选模式,用户可以像文件系统选中多个文件一样选中多个条目,Ctrl + 鼠标点击是离散多选,Shift + 鼠标点击是连续选中。<br>
新增的第二句代码是将 "自动排序" 复选框勾选,默认情况下列表控件的条目就是自动排序的。<br>
<br>
然后来看看 "添加" 按钮对应的槽函数代码:<br>
<div class="code"><span style=" color:#008000;">//支持一次添加多个音乐文件</span>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#808000;">void</span><span style=" color:#c0c0c0;"> </span><span style=" color:#800080;">Widget</span><span
style=" color:#000000;">::</span><span style=" color:#000000;">on_pushButtonAdd_clicked</span><span
style=" color:#000000;">()</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QStringList</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">slist</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">=</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#800080;">QFileDialog</span><span style=" color:#000000;">::</span><span
style=" color:#000000;">getOpenFileNames</span><span style=" color:#000000;">(</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">this</span><span
style=" color:#000000;">,</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">tr</span><span
style=" color:#000000;">(</span><span style=" color:#008000;">"添加多个音乐文件"</span><span
style=" color:#000000;">),</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">tr</span><span
style=" color:#000000;">(</span><span style=" color:#008000;">"."</span><span style=" color:#000000;">),</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">tr</span><span
style=" color:#000000;">(</span><span style=" color:#008000;">"Music</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">files(*.mp3</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">*.wma</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">*.wav);;All</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">files(*)"</span><span
style=" color:#000000;">)</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">);</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//判断文件名个数</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">int</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">nCount</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">=</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">slist</span><span style=" color:#000000;">.</span><span
style=" color:#000000;">count</span><span style=" color:#000000;">();</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">if</span><span
style=" color:#000000;">(</span><span style=" color:#000000;">nCount</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">&lt;</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000080;">1</span><span style=" color:#000000;">)</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">return</span><span
style=" color:#000000;">;</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">}</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//有选中的文件,逐个添加</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">for</span><span
style=" color:#000000;">(</span><span style=" color:#808000;">int</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">i</span><span style=" color:#000000;">=</span><span style=" color:#000080;">0</span><span
style=" color:#000000;">;</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">i</span><span
style=" color:#000000;">&lt;</span><span style=" color:#000000;">nCount</span><span
style=" color:#000000;">;</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">i</span><span
style=" color:#000000;">++)</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//新建条目,并自动加到列表控件</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QListWidgetItem</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">*</span><span style=" color:#000000;">theItem</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">=</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#808000;">new</span><span style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QListWidgetItem</span><span
style=" color:#000000;">(</span><span style=" color:#800000;">ui</span><span style=" color:#000000;">-&gt;</span><span
style=" color:#800000;">listWidget</span><span style=" color:#000000;">);</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//取出文件基本的短名设置为条目字符串</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QFileInfo</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">fi</span><span style=" color:#000000;">(</span><span
style=" color:#000000;">slist</span><span style=" color:#000000;">[</span><span
style=" color:#000000;">i</span><span style=" color:#000000;">]);</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">theItem</span><span
style=" color:#000000;">-&gt;</span><span style=" color:#000000;">setText</span><span
style=" color:#000000;">(</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">fi</span><span
style=" color:#000000;">.</span><span style=" color:#000000;">completeBaseName</span><span
style=" color:#000000;">()</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">);</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//设置全路径为工具提示信息</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">theItem</span><span
style=" color:#000000;">-&gt;</span><span style=" color:#000000;">setToolTip</span><span
style=" color:#000000;">(</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">fi</span><span
style=" color:#000000;">.</span><span style=" color:#000000;">absoluteFilePath</span><span
style=" color:#000000;">()</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">);</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">}</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//添加完毕</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">}</span></pre>
</div>
该槽函数里,先调用 QFileDialog::getOpenFileNames() 函数,弹出对话框可以选中多个音乐文件,这些文件名以
QStringList 列表对象返回。<br>
然后我们判断字符串列表对象 slist 是否包含有字符串,如果没有说明用户没选中文件,就不处理;<br>
如果用户选中某些文件,就利用 for 循环对这些文件逐个处理:<br>
&nbsp;&nbsp;&nbsp; 新建一个属于列表控件 ui-&gt;listWidget 的条目;<br>
&nbsp;&nbsp;&nbsp; 根据文件名字符串定义文件信息对象 fi;<br>
&nbsp;&nbsp;&nbsp; 提取文件基本名设置为新建条目的文本;<br>
&nbsp;&nbsp;&nbsp; 提取文件的绝对路径名设置为新建条目的工具提示信息。<br>
所有文件名字符串都处理完,该函数就结束了。<br>
注意这个例子只是处理文件名的列表,没有播放功能的。<br>
<br>
接着来看看 "删除" 按钮对应的槽函数代码:<br>
<div class="code"><span style=" color:#008000;">//支持一次删除多个条目</span>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#808000;">void</span><span style=" color:#c0c0c0;"> </span><span style=" color:#800080;">Widget</span><span
style=" color:#000000;">::</span><span style=" color:#000000;">on_pushButtonDel_clicked</span><span
style=" color:#000000;">()</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//获取已选中的列表条目</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QList</span><span
style=" color:#000000;">&lt;</span><span style=" color:#800080;">QListWidgetItem</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">*&gt;</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">itemList</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">=</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#800000;">ui</span><span style=" color:#000000;">-&gt;</span><span
style=" color:#800000;">listWidget</span><span style=" color:#000000;">-&gt;</span><span
style=" color:#000000;">selectedItems</span><span style=" color:#000000;">();</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//判断数目</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">int</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">nCount</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">=</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">itemList</span><span style=" color:#000000;">.</span><span
style=" color:#000000;">count</span><span style=" color:#000000;">();</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">if</span><span
style=" color:#000000;">(</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">nCount</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">&lt;</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000080;">1</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">)</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">return</span><span
style=" color:#000000;">;</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">}</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//有选中的条目需要删除</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//一般删除多个条目时,从尾部开始删除,这样删除过程中前面的条目行号不会变</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">for</span><span
style=" color:#000000;">(</span><span style=" color:#808000;">int</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">i</span><span style=" color:#000000;">=</span><span style=" color:#000000;">nCount</span><span
style=" color:#000000;">-</span><span style=" color:#000080;">1</span><span style=" color:#000000;">;</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">i</span><span style=" color:#000000;">&gt;=</span><span
style=" color:#000080;">0</span><span style=" color:#000000;">;</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">i</span><span style=" color:#000000;">--)</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//根据条目求出行号</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">int</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">theRow</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">=</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#800000;">ui</span><span style=" color:#000000;">-&gt;</span><span
style=" color:#800000;">listWidget</span><span style=" color:#000000;">-&gt;</span><span
style=" color:#000000;">row</span><span style=" color:#000000;">(</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">itemList</span><span style=" color:#000000;">[</span><span
style=" color:#000000;">i</span><span style=" color:#000000;">]</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">);</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//移除条目</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800000;">ui</span><span
style=" color:#000000;">-&gt;</span><span style=" color:#800000;">listWidget</span><span
style=" color:#000000;">-&gt;</span><span style=" color:#000000;">takeItem</span><span
style=" color:#000000;">(</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">theRow</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">);</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//彻底从内存删除</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">delete</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">itemList</span><span
style=" color:#000000;">[</span><span style=" color:#000000;">i</span><span style=" color:#000000;">];</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">itemList</span><span
style=" color:#000000;">[</span><span style=" color:#000000;">i</span><span style=" color:#000000;">]</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">=</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000080;">NULL</span><span style=" color:#000000;">;</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">}</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//清空临时条目列表</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">itemList</span><span
style=" color:#000000;">.</span><span style=" color:#000000;">clear</span><span
style=" color:#000000;">();</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">}</span></pre>
</div>
因为用户可能选中多个条目,所以不能用 ​currentItem() 函数,currentItem() 只能获取用户最后点击的一个高亮选中的条目。获取当前
选中的多个条目需要用 selectedItems() 函数,这个函数返回 QList&lt;QListWidgetItem *&gt; 列表。<br>
对于获取的选中条目列表 itemList,先判断个数,如果没有选中的就不处理;<br>
如果有选中的,就利用 for 循环挨个处理,注意删除操作一般从最后一个开始删除,这样前面的条目行号不会变,尽量少对前面条目造成影响,for 循环内部:<br>
&nbsp;&nbsp;&nbsp; 先根据条目获取条目在列表控件的序号 theRow ;<br>
&nbsp;&nbsp;&nbsp; 然后移除列表控件该行的条目,这只是解除隶属关系;<br>
&nbsp;&nbsp;&nbsp; 再手动调用 delete 函数删除条目内存,彻底删除掉。<br>
选中的条目都删除之后,把 itemList 也清空,这样就处理完毕了。<br>
<br>
以后读者如果遇到类似删除多个条目情况,建议是从末尾的条目开始删除,这样对前面的条目影响小,序号不容易出错,内存存储位置也较少腾挪,执行效率比较高。<br>
<br>
下面我们来看看两个关于排序的复选框对应的槽函数代码,两个复选框功能关系非常密切,"自动排序" 复选框的代码如下:<br>
<div class="code"><span style=" color:#008000;">//是否自动排序</span>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#808000;">void</span><span style=" color:#c0c0c0;"> </span><span style=" color:#800080;">Widget</span><span
style=" color:#000000;">::</span><span style=" color:#000000;">on_checkBoxAutoSort_clicked</span><span
style=" color:#000000;">(</span><span style=" color:#808000;">bool</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">checked</span><span style=" color:#000000;">)</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">if</span><span
style=" color:#000000;">(</span><span style=" color:#000000;">checked</span><span
style=" color:#000000;">)</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//开启自动排序</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800000;">ui</span><span
style=" color:#000000;">-&gt;</span><span style=" color:#800000;">listWidget</span><span
style=" color:#000000;">-&gt;</span><span style=" color:#000000;">setSortingEnabled</span><span
style=" color:#000000;">(</span><span style=" color:#808000;">true</span><span style=" color:#000000;">);</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//把逆序排列的复选框启用</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800000;">ui</span><span
style=" color:#000000;">-&gt;</span><span style=" color:#800000;">checkBoxReverse</span><span
style=" color:#000000;">-&gt;</span><span style=" color:#000000;">setEnabled</span><span
style=" color:#000000;">(</span><span style=" color:#808000;">true</span><span style=" color:#000000;">);</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//判断是正序还是逆序</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">if</span><span
style=" color:#000000;">(</span><span style=" color:#c0c0c0;"> </span><span style=" color:#800000;">ui</span><span
style=" color:#000000;">-&gt;</span><span style=" color:#800000;">checkBoxReverse</span><span
style=" color:#000000;">-&gt;</span><span style=" color:#000000;">checkState</span><span
style=" color:#000000;">()</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">!=</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">Qt</span><span style=" color:#000000;">::</span><span
style=" color:#800080;">Checked</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">)</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//正序</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800000;">ui</span><span
style=" color:#000000;">-&gt;</span><span style=" color:#800000;">listWidget</span><span
style=" color:#000000;">-&gt;</span><span style=" color:#000000;">sortItems</span><span
style=" color:#000000;">(</span><span style=" color:#800080;">Qt</span><span style=" color:#000000;">::</span><span
style=" color:#800080;">AscendingOrder</span><span style=" color:#000000;">);</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">}</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">else</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//逆序</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800000;">ui</span><span
style=" color:#000000;">-&gt;</span><span style=" color:#800000;">listWidget</span><span
style=" color:#000000;">-&gt;</span><span style=" color:#000000;">sortItems</span><span
style=" color:#000000;">(</span><span style=" color:#800080;">Qt</span><span style=" color:#000000;">::</span><span
style=" color:#800080;">DescendingOrder</span><span style=" color:#000000;">);</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">}</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">}</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">else</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//不自动排序</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800000;">ui</span><span
style=" color:#000000;">-&gt;</span><span style=" color:#800000;">listWidget</span><span
style=" color:#000000;">-&gt;</span><span style=" color:#000000;">setSortingEnabled</span><span
style=" color:#000000;">(</span><span style=" color:#808000;">false</span><span
style=" color:#000000;">);</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//禁用逆序复选框</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800000;">ui</span><span
style=" color:#000000;">-&gt;</span><span style=" color:#800000;">checkBoxReverse</span><span
style=" color:#000000;">-&gt;</span><span style=" color:#000000;">setEnabled</span><span
style=" color:#000000;">(</span><span style=" color:#808000;">false</span><span
style=" color:#000000;">);</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">}</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">}</span></pre>
</div>
如果用户勾选了 "自动排序" 复选框:<br>
&nbsp;&nbsp;&nbsp; 调用列表控件的函数 setSortingEnabled(true),开启自动排序;<br>
&nbsp;&nbsp;&nbsp; 因为启动了自动排序,这样 "逆序排列" 复选框就需要用到了,启用 "逆序排列" 复选框;<br>
&nbsp;&nbsp;&nbsp; 根据 "逆序排列" 复选框的状态,判断是应该自动按照正序排列,还是自动按照逆序排列。<br>
如果用户取消 "自动排序" 复选的勾选状态:<br>
&nbsp;&nbsp;&nbsp; 调用列表空的函数 setSortingEnabled(false) 关闭自动排序;<br>
&nbsp;&nbsp;&nbsp; 因为自动排序关了,那么也就没有正序逆序之分,就把 "逆序排列" 复选框设置为禁用状态。<br>
<br>
上面代码保证了只有在开启自动排序的情况下,才让 "逆序排列" 复选框处于可用状态,让用户选择是逆序还是正序排列。然后来看看 "逆序排列"
复选框对应槽函数的代码:<br>
<div class="code"><span style=" color:#008000;">//是否逆序排列</span>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#808000;">void</span><span style=" color:#c0c0c0;"> </span><span style=" color:#800080;">Widget</span><span
style=" color:#000000;">::</span><span style=" color:#000000;">on_checkBoxReverse_clicked</span><span
style=" color:#000000;">(</span><span style=" color:#808000;">bool</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">checked</span><span style=" color:#000000;">)</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">if</span><span
style=" color:#000000;">(</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">!</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">checked</span><span
style=" color:#000000;">)</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//正序</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800000;">ui</span><span
style=" color:#000000;">-&gt;</span><span style=" color:#800000;">listWidget</span><span
style=" color:#000000;">-&gt;</span><span style=" color:#000000;">sortItems</span><span
style=" color:#000000;">(</span><span style=" color:#800080;">Qt</span><span style=" color:#000000;">::</span><span
style=" color:#800080;">AscendingOrder</span><span style=" color:#000000;">);</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">}</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">else</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//逆序</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800000;">ui</span><span
style=" color:#000000;">-&gt;</span><span style=" color:#800000;">listWidget</span><span
style=" color:#000000;">-&gt;</span><span style=" color:#000000;">sortItems</span><span
style=" color:#000000;">(</span><span style=" color:#800080;">Qt</span><span style=" color:#000000;">::</span><span
style=" color:#800080;">DescendingOrder</span><span style=" color:#000000;">);</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">}</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">}</span></pre>
</div>
这个槽函数代码比较简单,如果没选中该复选框,就是正序排列;<br>
如果选中了该复选框,就是按照逆序排列。<br>
&nbsp;"逆序排列" 复选框主要是在开启自动排序的情况下起作用,其他时候是用不着的。<br>
<br>
接下来我们看看 "导出m3u" 按钮的功能代码,导出时,列表控件里的条目按什么样的顺序排列,导出的 m3u 播放列表文件内部就是什么样的顺序排列:<br>
<div class="code"><span style=" color:#008000;">//</span><span style=" color:#c0c0c0;">
</span><span style=" color:#008000;">这里导出为最简单的</span><span style=" color:#c0c0c0;">
</span><span style=" color:#008000;">m3u</span><span style=" color:#c0c0c0;">
</span><span style=" color:#008000;">格式列表</span>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#808000;">void</span><span style=" color:#c0c0c0;"> </span><span style=" color:#800080;">Widget</span><span
style=" color:#000000;">::</span><span style=" color:#000000;">on_pushButtonExportM3U_clicked</span><span
style=" color:#000000;">()</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//判断列表条目总数</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">int</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">nCount</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">=</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#800000;">ui</span><span style=" color:#000000;">-&gt;</span><span
style=" color:#800000;">listWidget</span><span style=" color:#000000;">-&gt;</span><span
style=" color:#000000;">count</span><span style=" color:#000000;">();</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">if</span><span
style=" color:#000000;">(</span><span style=" color:#000000;">nCount</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">&lt;</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000080;">1</span><span style=" color:#000000;">)</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">return</span><span
style=" color:#000000;">;</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">}</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//获取要保存的文件名</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QString</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">strName</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">=</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#800080;">QFileDialog</span><span style=" color:#000000;">::</span><span
style=" color:#000000;">getSaveFileName</span><span style=" color:#000000;">(</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">this</span><span
style=" color:#000000;">,</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">tr</span><span
style=" color:#000000;">(</span><span style=" color:#008000;">"保存为</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;">M3U</span><span style=" color:#c0c0c0;"> </span><span style=" color:#008000;">文件"</span><span
style=" color:#000000;">),</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">tr</span><span
style=" color:#000000;">(</span><span style=" color:#008000;">"."</span><span style=" color:#000000;">),</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">tr</span><span
style=" color:#000000;">(</span><span style=" color:#008000;">"M3U</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;">files(*.m3u)"</span><span style=" color:#000000;">)</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">);</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//判断文件名</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">if</span><span
style=" color:#000000;">(</span><span style=" color:#000000;">strName</span><span
style=" color:#000000;">.</span><span style=" color:#000000;">isEmpty</span><span
style=" color:#000000;">())</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">return</span><span
style=" color:#000000;">;</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">}</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//打开文件</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QFile</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">fileOut</span><span
style=" color:#000000;">(</span><span style=" color:#000000;">strName</span><span
style=" color:#000000;">);</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">QIODevice::Text</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">自动转换换行符为本地系统风格</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">if</span><span
style=" color:#000000;">(</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">!</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">fileOut</span><span
style=" color:#000000;">.</span><span style=" font-style:italic; color:#000000;">open</span><span
style=" color:#000000;">(</span><span style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QIODevice</span><span
style=" color:#000000;">::</span><span style=" color:#800080;">WriteOnly</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">|</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#800080;">QIODevice</span><span style=" color:#000000;">::</span><span
style=" color:#800080;">Text</span><span style=" color:#000000;">)</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">)</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QMessageBox</span><span
style=" color:#000000;">::</span><span style=" color:#000000;">warning</span><span
style=" color:#000000;">(</span><span style=" color:#808000;">this</span><span style=" color:#000000;">,</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">tr</span><span style=" color:#000000;">(</span><span
style=" color:#008000;">"打开文件"</span><span style=" color:#000000;">),</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">tr</span><span
style=" color:#000000;">(</span><span style=" color:#008000;">"无法打开指定文件,请检查是否有写入权限!"</span><span
style=" color:#000000;">));</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">return</span><span
style=" color:#000000;">;</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">}</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//正确打开之后,定义文本流</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//文本流自动转换文本编码为本地系统格式</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//但文本流不处理换行符,换行符本地化通过文件打开时的</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">QIODevice::Text</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">指定</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QTextStream</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">tsOut</span><span
style=" color:#000000;">(&amp;</span><span style=" color:#000000;">fileOut</span><span
style=" color:#000000;">);</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//先写入文件头</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">tsOut</span><span
style=" color:#000000;">&lt;&lt;</span><span style=" color:#000000;">tr</span><span
style=" color:#000000;">(</span><span style=" color:#008000;">"#EXTM3U"</span><span
style=" color:#000000;">)&lt;&lt;</span>endl<span style=" color:#000000;">;</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//逐个文件名条目写入</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">for</span><span
style=" color:#000000;">(</span><span style=" color:#808000;">int</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">i</span><span style=" color:#000000;">=</span><span style=" color:#000080;">0</span><span
style=" color:#000000;">;</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">i</span><span
style=" color:#000000;">&lt;</span><span style=" color:#000000;">nCount</span><span
style=" color:#000000;">;</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">i</span><span
style=" color:#000000;">++)</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QString</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">strCurName</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">=</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#800000;">ui</span><span style=" color:#000000;">-&gt;</span><span
style=" color:#800000;">listWidget</span><span style=" color:#000000;">-&gt;</span><span
style=" color:#000000;">item</span><span style=" color:#000000;">(</span><span style=" color:#000000;">i</span><span
style=" color:#000000;">)-&gt;</span><span style=" color:#000000;">toolTip</span><span
style=" color:#000000;">();</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">tsOut</span><span
style=" color:#000000;">&lt;&lt;</span><span style=" color:#000000;">strCurName</span><span
style=" color:#000000;">&lt;&lt;</span>endl<span style=" color:#000000;">;</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">}</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//完成</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">}</span></pre>
</div>
该槽函数开始时先判断列表控件内的条目总数,如果没条目就不导出,如果有条目才进行后续操作。<br>
然后获取要保存的文件名 strName ,判断文件名非空再进行后续处理。<br>
根据非空文件名定义文件对象 fileOut,以只读和文本模式 QIODevice::Text 打开该文件,文本模式 QIODevice::Text
可以在文件写入时把换行符("\n"、endl)自动转为本地系统风格写入文件中,Windows换行风格是 "\r\n" ,其他系统一般只是 "\n"
换行。<br>
文件正确打开之后,定义文本流 tsOut 用于写入内容。<br>
文本流先写入文件头一行 "#EXTM3U" ;<br>
然后用 for 循环将每个列表条目工具提示里存的音乐文件绝对路径,写入到文本流。<br>
这样就完成了 *.m3u 文件的导出,这种播放列表文件可以用千千静听等播放器打开。<br>
<br>
最后一个按钮是 "查找" 按钮,对应的功能代码如下:<br>
<div class="code"><span style=" color:#008000;">//条目文本查找,包含模板字符串的都高亮显示</span>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#808000;">void</span><span style=" color:#c0c0c0;"> </span><span style=" color:#800080;">Widget</span><span
style=" color:#000000;">::</span><span style=" color:#000000;">on_pushButtonFind_clicked</span><span
style=" color:#000000;">()</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//获取模板字符串</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QString</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">strTemplate</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">=</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#800000;">ui</span><span style=" color:#000000;">-&gt;</span><span
style=" color:#800000;">lineEditTemplate</span><span style=" color:#000000;">-&gt;</span><span
style=" color:#000000;">text</span><span style=" color:#000000;">();</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//判断字符串是否为空</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">if</span><span
style=" color:#000000;">(</span><span style=" color:#000000;">strTemplate</span><span
style=" color:#000000;">.</span><span style=" color:#000000;">isEmpty</span><span
style=" color:#000000;">())</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">return</span><span
style=" color:#000000;">;</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">}</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//先把旧的高亮显示条目都清空</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800000;">ui</span><span
style=" color:#000000;">-&gt;</span><span style=" color:#800000;">listWidget</span><span
style=" color:#000000;">-&gt;</span><span style=" color:#000000;">setCurrentItem</span><span
style=" color:#000000;">(</span><span style=" color:#000080;">NULL</span><span style=" color:#000000;">,</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QItemSelectionModel</span><span
style=" color:#000000;">::</span><span style=" color:#800080;">Clear</span><span
style=" color:#000000;">);</span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//查找匹配的条目文本,第二个参数控制匹配行为</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QList</span><span
style=" color:#000000;">&lt;</span><span style=" color:#800080;">QListWidgetItem</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">*&gt;</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">list</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">=</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800000;">ui</span><span
style=" color:#000000;">-&gt;</span><span style=" color:#800000;">listWidget</span><span
style=" color:#000000;">-&gt;</span><span style=" color:#000000;">findItems</span><span
style=" color:#000000;">(</span><span style=" color:#000000;">strTemplate</span><span
style=" color:#000000;">,</span><span style=" color:#c0c0c0;"> </span><span style=" color:#800080;">Qt</span><span
style=" color:#000000;">::</span><span style=" color:#800080;">MatchContains</span><span
style=" color:#000000;">);</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//判断是否有匹配的</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">int</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">nCount</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">=</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">list</span><span style=" color:#000000;">.</span><span style=" color:#000000;">count</span><span
style=" color:#000000;">();</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">if</span><span
style=" color:#000000;">(</span><span style=" color:#000000;">nCount</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">&lt;</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000080;">1</span><span style=" color:#000000;">)</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QMessageBox</span><span
style=" color:#000000;">::</span><span style=" color:#000000;">information</span><span
style=" color:#000000;">(</span><span style=" color:#808000;">this</span><span style=" color:#000000;">,</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">tr</span><span style=" color:#000000;">(</span><span
style=" color:#008000;">"查找条目"</span><span style=" color:#000000;">),</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">tr</span><span
style=" color:#000000;">(</span><span style=" color:#008000;">"没有找到匹配的条目文本。"</span><span
style=" color:#000000;">));</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">return</span><span
style=" color:#000000;">;</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">}</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//把第一个匹配的条目设置为当前条目</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800000;">ui</span><span
style=" color:#000000;">-&gt;</span><span style=" color:#800000;">listWidget</span><span
style=" color:#000000;">-&gt;</span><span style=" color:#000000;">setCurrentItem</span><span
style=" color:#000000;">(</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">list</span><span
style=" color:#000000;">[</span><span style=" color:#000080;">0</span><span style=" color:#000000;">]</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">);</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//自动滚动到第一条匹配选中的条目,这个条目显示在可视区域顶部</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800000;">ui</span><span
style=" color:#000000;">-&gt;</span><span style=" color:#800000;">listWidget</span><span
style=" color:#000000;">-&gt;</span><span style=" color:#000000;">scrollToItem</span><span
style=" color:#000000;">(</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">list</span><span
style=" color:#000000;">[</span><span style=" color:#000080;">0</span><span style=" color:#000000;">],</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QAbstractItemView</span><span
style=" color:#000000;">::</span><span style=" color:#800080;">PositionAtTop</span><span
style=" color:#000000;">);</span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//然后再把所有匹配的条目设置为高亮选中</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">for</span><span
style=" color:#000000;">(</span><span style=" color:#808000;">int</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">i</span><span style=" color:#000000;">=</span><span style=" color:#000080;">0</span><span
style=" color:#000000;">;</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">i</span><span
style=" color:#000000;">&lt;</span><span style=" color:#000000;">nCount</span><span
style=" color:#000000;">;</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">i</span><span
style=" color:#000000;">++)</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">list</span><span
style=" color:#000000;">[</span><span style=" color:#000000;">i</span><span style=" color:#000000;">]-&gt;</span><span
style=" color:#000000;">setSelected</span><span style=" color:#000000;">(</span><span
style=" color:#808000;">true</span><span style=" color:#000000;">);</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//条目自己可以设置高亮选中</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">}</span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//将显示焦点切换到列表控件</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800000;">ui</span><span
style=" color:#000000;">-&gt;</span><span style=" color:#800000;">listWidget</span><span
style=" color:#000000;">-&gt;</span><span style=" color:#000000;">setFocus</span><span
style=" color:#000000;">();</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">}</span></pre>
</div>
这个槽函数功能就是根据单行编辑器里的文本,查找包含该文本的条目。<br>
槽函数先获取单行编辑器里的模板字符串 strTemplate,字符串非空才进行后续操作。<br>
因为我们要把所有匹配的条目都高亮显示,所以调用列表控件的 setCurrentItem(NULL,
QItemSelectionModel::Clear) 函数,把之前选中的状态都清了。<br>
然后调用列表控件的 findItems(strTemplate, Qt::MatchContains)
查找包含模板字符串的条目,这个函数第二个参数可以控制匹配行为,Qt::MatchContains 是包含模板字符串,而其他的,比如
Qt::MatchWildcard 是根据通配符(* ?)进行匹配。查找的结果以 QList&lt;QListWidgetItem *&gt;
类型的对象返回。<br>
得到查找结果 list 之后,先判断个数,如果没有就提示没有找到匹配的条目;<br>
如果找到了匹配的条目,那么:<br>
把第一个匹配的条目设置为列表控件当前高亮选中的条目;<br>
并滚动到第一个匹配的条目的位置,这个条目会尽量滚动到列表控件可视区域的顶部(QAbstractItemView::PositionAtTop );<br>
现在只处理了第一个匹配的,然后我们再把匹配条目列表 list 里的所有条目用 for 循环处理一遍,把每个匹配的条目都设置为高亮选中状态;<br>
最后再把显示焦点转移到列表控件,因为用户点击 "查找"
按钮时,焦点在该按钮上,焦点不在列表控件时,列表控件选中的条目是灰色的,转移焦点到列表控件后,列表控件内选中的所有条目都是高亮蓝色的,这样看起来更清晰。<br>
<br>
例子的代码就讲到这,下面运行例子看看效果,我们添加很多的音乐文件条目之后,随便查找一个:<br>
<center><img src="images/ch08/ch08-01-28.png" alt="run"></center>
匹配的第一个条目会自动滚到显示区域顶部位置,匹配的条目都会高亮显示。还有其他按钮的功能,读者可以都测试一下,导出的 m3u
播放列表可以用千千静听等打开试试。<br>
本节的主要内容就讲解到这,后面留几个小练习,建议读者都动手实践一下,因为靠瞎蒙是学不到东西的。<br>
<br>
<br>
<br>
<div class="practice">
<table>
<tbody>
<tr>
<td><img src="images/pics/practice.png" alt="tip"></td>
<td> <b>练习</b> </td>
</tr>
</tbody>
</table>
① 游戏装备列表示例中,加载文件的函数 on_pushButtonLoad_clicked() 最后的 for
循环内部的代码,如果注释掉末尾的&nbsp; theItem-&gt;setFlags(***) 这行代码,会有什么影响?<br>
<br>
② 还是游戏装备列表示例中,加载文件的函数 on_pushButtonLoad_clicked(),这个函数加载文件中新条目之前,没有调用
clear() 函数清除旧的列表。如果我们勾选 6 个装备,保存为文件,勾选状态会存到文件里,我们再立即加载该文件,会出现什么现象?会不会同时携带
12 个装备?<br>
<br>
③ 歌曲列表示例中,条目都没有图标,请去网上下载 mp3、wma、wav 三种文件格式的图标,添加为示例程序内部资源,然后在 "添加"
按钮的槽函数代码里根据每个音乐文件的扩展名,为条目添加相对应的图标。<br>
</div>
<br>
<br>
<br>
<table style="text-align: left; width: 100%;" border="0" cellpadding="2" cellspacing="2">
<tbody>
<tr>
<td style="width: 40%;">
<div style="text-align: center;"><a href="ch08-00.htm"><img class="pic"
style="width: 32px; height: 32px;" alt="prev" src="images/pics/prev.png"></a></div>
</td>
<td style="width: 20%;">
<div style="text-align: center;"><a href="contents.htm"><img class="pic"
style="width: 32px; height: 32px;" alt="contents" src="images/pics/contents.png"></a></div>
</td>
<td style="width: 40%;">
<div style="text-align: center;"><a href="ch08-02.htm"><img class="pic"
style="width: 32px; height: 32px;" alt="next" src="images/pics/next.png"></a></div>
</td>
</tr>
</tbody>
</table>
</body>
</html>
HTML
1
https://gitee.com/qtguide/qtguide.git
git@gitee.com:qtguide/qtguide.git
qtguide
qtguide
qtguide
master

搜索帮助