?? tutorial2-05.html
字號(hào):
<a name="2-1"></a><p> <pre> void ChartForm::init()
{
<a href="qwidget.html#setCaption">setCaption</a>( "Chart" );
m_filename = <a href="qstring.html#QString-null">QString::null</a>;
m_changed = false;
m_elements[0] = Element( Element::INVALID, red );
m_elements[1] = Element( Element::INVALID, cyan );
m_elements[2] = Element( Element::INVALID, blue );
</pre><tt>...</tt>
<p> 我們使用了init()函數(shù)是因?yàn)槲覀兿朐谝暣氨粯?gòu)造的時(shí)候和無論用戶載入一個(gè)存在的數(shù)據(jù)組或者創(chuàng)建一個(gè)新的數(shù)據(jù)組的時(shí)候初始化畫布和元素(在<tt>m_elements</tt> <tt>ElementVector</tt>中)。
<p> 我們重新設(shè)置標(biāo)題并設(shè)置當(dāng)前文件名稱為QString::null。我們也用無效的元素來組裝元素矢量。這不是必需的,但是給每一個(gè)元素一個(gè)不同的顏色對于用戶來講是更方便的,因?yàn)楫?dāng)他們輸入值的時(shí)候每一個(gè)都會(huì)已經(jīng)有了一個(gè)確定的顏色(當(dāng)然他們可以修改)。
<p> <h2> 文件處理動(dòng)作
</h2>
<a name="3"></a><p> <h3> okToClear()
</h3>
<a name="3-1"></a><p> <pre> bool ChartForm::okToClear()
{
if ( m_changed ) {
<a href="qstring.html">QString</a> msg;
if ( m_filename.isEmpty() )
msg = "Unnamed chart ";
else
msg = QString( "Chart '%1'\n" ).arg( m_filename );
msg += "has been changed.";
switch( QMessageBox::<a href="qmessagebox.html#information">information</a>( this, "Chart -- Unsaved Changes",
msg, "&Save", "Cancel", "&Abandon",
0, 1 ) ) {
case 0:
fileSave();
break;
case 1:
default:
return false;
break;
case 2:
break;
}
}
return true;
}
</pre>
<p> okToClear()函數(shù)用來提示用戶在有沒保存的數(shù)據(jù)的時(shí)候保存它們。它也被其它幾個(gè)函數(shù)使用。
<p> <h3> fileNew()
</h3>
<a name="3-2"></a><p>
<pre> void ChartForm::fileNew()
{
if ( okToClear() ) {
init();
drawElements();
}
}
</pre>
<p> 當(dāng)用戶調(diào)用fileNew()動(dòng)作時(shí),我們調(diào)用okToClear()來給他們一個(gè)保存任何為保存的數(shù)據(jù)的機(jī)會(huì)。無論他們保存或者放棄或者沒有任何為保存的數(shù)據(jù),我們都重新初始化元素矢量并繪制默認(rèn)圖表。
<p> <center><table cellpadding="4" cellspacing="2" border="0">
<tr bgcolor="#d0d0d0">
<td valign="top">我們是不是也應(yīng)該調(diào)用optionsSetData()來彈出一個(gè)對話框,讓用戶通過它來創(chuàng)建和編輯值、顏色等等呢?你可以運(yùn)行一下現(xiàn)在的應(yīng)用程序,然后試著把optionsSetData()的調(diào)用添加進(jìn)去后再運(yùn)行并觀察它們來決定你更喜歡哪一個(gè)。
</table></center>
<p> <h3> fileOpen()
</h3>
<a name="3-3"></a><p> <pre> void ChartForm::fileOpen()
{
if ( !okToClear() )
return;
<a name="x2414"></a> <a href="qstring.html">QString</a> filename = QFileDialog::<a href="qfiledialog.html#getOpenFileName">getOpenFileName</a>(
QString::null, "Charts (*.cht)", this,
"file open", "Chart -- File Open" );
<a name="x2417"></a> if ( !filename.<a href="qstring.html#isEmpty">isEmpty</a>() )
load( filename );
else
<a href="qmainwindow.html#statusBar">statusBar</a>()->message( "File Open abandoned", 2000 );
}
</pre>
<p> 我們檢查它是否是okToClear()。如果是的話,我們使用靜態(tài)的<a href="qfiledialog.html#getOpenFileName">QFileDialog::getOpenFileName</a>()函數(shù)來獲得用戶想要載入的文件的名稱。如果我們得到一個(gè)文件名,我們就調(diào)用load()。
<p> <h3> fileSaveAs()
</h3>
<a name="3-4"></a><p> <pre> void ChartForm::fileSaveAs()
{
<a name="x2415"></a> <a href="qstring.html">QString</a> filename = QFileDialog::<a href="qfiledialog.html#getSaveFileName">getSaveFileName</a>(
QString::null, "Charts (*.cht)", this,
"file save as", "Chart -- File Save As" );
if ( !filename.<a href="qstring.html#isEmpty">isEmpty</a>() ) {
int answer = 0;
<a name="x2413"></a> if ( QFile::<a href="qfile.html#exists">exists</a>( filename ) )
<a name="x2416"></a> answer = QMessageBox::<a href="qmessagebox.html#warning">warning</a>(
this, "Chart -- Overwrite File",
QString( "Overwrite\n\'%1\'?" ).
arg( filename ),
"&Yes", "&No", QString::null, 1, 1 );
if ( answer == 0 ) {
m_filename = filename;
updateRecentFiles( filename );
fileSave();
return;
}
}
<a href="qmainwindow.html#statusBar">statusBar</a>()->message( "Saving abandoned", 2000 );
}
</pre>
<p> 這個(gè)函數(shù)調(diào)用了靜態(tài)的<a href="qfiledialog.html#getSaveFileName">QFileDialog::getSaveFileName</a>()來得到一個(gè)要保存數(shù)據(jù)的文件的明處那個(gè)。如果文件存在,我們使用使用一個(gè)<a href="qmessagebox.html#warning">QMessageBox::warning</a>()來提醒用戶并給他們一個(gè)放棄保存的選擇。如果文件被保存了我們就更新最近打開的文件列表并調(diào)用fileSave()(在<a href="tutorial2-07.html">文件處理</a>中)來執(zhí)行存儲(chǔ)。
<p> <h2> 管理最近打開文件的列表
</h2>
<a name="4"></a><p>
<pre> <a href="qstringlist.html">QStringList</a> m_recentFiles;
</pre>
<p> 我們用一個(gè)字符串列表來處理這個(gè)最近打開文件的列表。
<p>
<pre> void ChartForm::updateRecentFilesMenu()
{
for ( int i = 0; i < MAX_RECENTFILES; ++i ) {
if ( fileMenu-><a href="qmenudata.html#findItem">findItem</a>( i ) )
fileMenu-><a href="qmenudata.html#removeItem">removeItem</a>( i );
if ( i < int(m_recentFiles.count()) )
fileMenu-><a href="qmenudata.html#insertItem">insertItem</a>( QString( "&%1 %2" ).
arg( i + 1 ).arg( m_recentFiles[i] ),
this, SLOT( fileOpenRecent(int) ),
0, i );
}
}
</pre>
<p> 無論用戶打開一個(gè)存在的文件或者保存一個(gè)新文件的時(shí)候,這個(gè)函數(shù)會(huì)被調(diào)用(通常是通過updateRecentFiles())。對于這個(gè)字符串列表中的每一個(gè)文件我們都插入一個(gè)新的菜單條目。我們在每一個(gè)文件名的前面都加上一個(gè)從<u>1</u>到<u>9</u>帶下劃線的數(shù)字,這樣就可以支持鍵盤操作(比如,<tt>Alt+F,2</tt>就可以打開列表中的第二個(gè)文件)。我們給每一個(gè)菜單條目一個(gè)和它們在字符串列表中的索引位置相同的數(shù)值作為id,并且把每一個(gè)菜單條目都和fileOpenRecent()槽相連。老的文件菜單條目會(huì)在每一個(gè)最新的文件菜單條目id來到的同時(shí)被刪除。它會(huì)工作是因?yàn)槠渌募藛螚l目都有一個(gè)由Qt生成的id(它們都是<0的),然而我們所創(chuàng)建的菜單條目的id都是>=0的。
<p>
<pre> void ChartForm::updateRecentFiles( const <a href="qstring.html">QString</a>& filename )
{
if ( m_recentFiles.find( filename ) != m_recentFiles.end() )
return;
m_recentFiles.push_back( filename );
if ( m_recentFiles.count() > MAX_RECENTFILES )
m_recentFiles.pop_front();
updateRecentFilesMenu();
}
</pre>
<p> 當(dāng)用戶打開一個(gè)存在的文件或者保存一個(gè)新文件的時(shí)候,它會(huì)被調(diào)用。如果文件已經(jīng)存在于列表中,它就會(huì)很簡單地返回。否則這個(gè)文件會(huì)被添加到列表的末尾并且如果列表太大(>9個(gè)文件)的話,第一個(gè)(最老的)就會(huì)被移去。然后updateRecentFilesMenu()被調(diào)用來在File菜單中重新創(chuàng)建最近使用的文件列表。
<p>
<pre> void ChartForm::fileOpenRecent( int index )
{
if ( !okToClear() )
return;
load( m_recentFiles[index] );
}
</pre>
<p> 當(dāng)用戶選擇了一個(gè)最近打開的文件時(shí),fileOpenRecent()槽會(huì)伴隨一個(gè)用戶選擇的文件的菜單id而被調(diào)用。因?yàn)槲覀兪刮募藛蔚膇d和文件在<tt>m_recentFiles</tt>列表中的索引位置相等,我們就可以很簡單的通過文件的菜單條目id來載入了。
<p> <h2> 退出
</h2>
<a name="5"></a><p> <pre> void ChartForm::fileQuit()
{
if ( okToClear() ) {
saveOptions();
qApp-><a href="qapplication.html#exit">exit</a>( 0 );
}
}
</pre>
<p> 當(dāng)用戶退出時(shí),我們給他們保存任何未保存數(shù)據(jù)的機(jī)會(huì)(okToClear()),然后在結(jié)束之前保存它們的選項(xiàng),比如窗口的大小和位置、圖表類型等等。
<p> <pre> void ChartForm::saveOptions()
{
<a href="qsettings.html">QSettings</a> settings;
settings.<a href="qsettings.html#insertSearchPath">insertSearchPath</a>( QSettings::Windows, WINDOWS_REGISTRY );
settings.<a href="qsettings.html#writeEntry">writeEntry</a>( APP_KEY + "WindowWidth", width() );
settings.<a href="qsettings.html#writeEntry">writeEntry</a>( APP_KEY + "WindowHeight", height() );
settings.<a href="qsettings.html#writeEntry">writeEntry</a>( APP_KEY + "WindowX", x() );
settings.<a href="qsettings.html#writeEntry">writeEntry</a>( APP_KEY + "WindowY", y() );
settings.<a href="qsettings.html#writeEntry">writeEntry</a>( APP_KEY + "ChartType", int(m_chartType) );
settings.<a href="qsettings.html#writeEntry">writeEntry</a>( APP_KEY + "AddValues", int(m_addValues) );
settings.<a href="qsettings.html#writeEntry">writeEntry</a>( APP_KEY + "Decimals", m_decimalPlaces );
settings.<a href="qsettings.html#writeEntry">writeEntry</a>( APP_KEY + "Font", m_font.toString() );
for ( int i = 0; i < int(m_recentFiles.count()); ++i )
settings.<a href="qsettings.html#writeEntry">writeEntry</a>( APP_KEY + "File" + QString::number( i + 1 ),
m_recentFiles[i] );
}
</pre>
<p> 直接使用<a href="qsettings.html">QSettings</a>來保存用戶選項(xiàng)。
<p> <h2> 自定義對話框
</h2>
<a name="6"></a><p> 我們想讓用戶可以手工地設(shè)置一些選項(xiàng)并且創(chuàng)建和編輯值、值顏色等等。
<p>
<pre> void ChartForm::optionsSetOptions()
{
OptionsForm *optionsForm = new OptionsForm( this );
optionsForm->chartTypeComboBox->setCurrentItem( m_chartType );
optionsForm-><a href="qwidget.html#setFont">setFont</a>( m_font );
</pre><pre> if ( optionsForm-><a href="qdialog.html#exec">exec</a>() ) {
setChartType( ChartType(
optionsForm->chartTypeComboBox->currentItem()) );
m_font = optionsForm-><a href="qwidget.html#font">font</a>();
</pre><pre> drawElements();
}
delete optionsForm;
}
</pre>
<p> 設(shè)置選項(xiàng)的視窗是由我們自定義的<tt>OptionsForm</tt>提供的,在<a href="tutorial2-09.html">設(shè)置選項(xiàng)</a>中。這個(gè)選項(xiàng)視窗是一個(gè)標(biāo)準(zhǔn)的“啞的”對話框:我們創(chuàng)建一個(gè)實(shí)例,把所有的圖形用戶界面元素都和所有相關(guān)的設(shè)置都組裝起來,并且如果用戶點(diǎn)擊了“OK”(exec()返回一個(gè)真值)我們就會(huì)從圖形用戶界面元素中讀取設(shè)置。
<pre> void ChartForm::optionsSetData()
{
SetDataForm *setDataForm = new SetDataForm( &m_elements, m_decimalPlaces, this );
if ( setDataForm-><a href="qdialog.html#exec">exec</a>() ) {
m_changed = true;
drawElements();
}
delete setDataForm;
}
</pre>
<p> 創(chuàng)建和編輯圖表數(shù)據(jù)的視窗由我們自定義的<tt>SetDataForm</tt>提供,在<a href="tutorial2-08.html">獲得數(shù)據(jù)</a>中。這個(gè)視窗是一個(gè)“聰明的”對話框。我們傳入我們想要使用的數(shù)據(jù)結(jié)構(gòu),并且對話框可以自己處理數(shù)據(jù)機(jī)構(gòu)的表達(dá)。如果用戶點(diǎn)擊“OK”,對話框會(huì)更新數(shù)據(jù)結(jié)構(gòu)并且exec()會(huì)返回一個(gè)真值。如果用戶改變了數(shù)據(jù)時(shí)我們在optionsSetData()中所要做的時(shí)把圖表標(biāo)記為changed并調(diào)用drawElements()來使用新的和更新過的數(shù)據(jù)來重新繪制圖表。
<p> <p align=right>
<a href="tutorial2-04.html">« 主體很容易</a> |
<a href="tutorial2.html">目錄</a> |
<a href="tutorial2-06.html">畫布控制 »</a>
</p>
<p>
<!-- eof -->
<p><address><hr><div align=center>
<table width=100% cellspacing=0 border=0><tr>
<td>Copyright © 2002
<a href="http://www.trolltech.com">Trolltech</a>
<td><a href="http://www.trolltech.com/trademarks.html">Trademarks</a>
<td><a href="zh_CN.html">譯者:Cavendish</a>
<td align=right><div align=right>Qt 3.0.5版</div>
</table></div></address></body>
</html>
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -