Difference between revisions of "Archive:Development/Tutorials/Using KActions (zh TW)"

 
(8 intermediate revisions by 2 users not shown)
Line 1: Line 1:
{{Template:I18n/Language Navigation Bar|Development/Tutorials/Using_KActions}}
+
{{Template:I18n/Language Navigation Bar_(zh_TW)|Development/Tutorials/Using_KActions}}
  
 
{{TutorialBrowser (zh TW)|
 
{{TutorialBrowser (zh TW)|
Line 7: Line 7:
 
name=如何使用 KActions 和 XMLGUI|
 
name=如何使用 KActions 和 XMLGUI|
  
pre=[[Development/Tutorials/Using_KXmlGuiWindow (zh TW)|教學 2 - KXmlGuiWindow]],XML 基礎知識|
+
pre=[[Development/Tutorials/Using_KXmlGuiWindow (zh TW)|教學 2 - KXmlGuiWindow]]、XML 基礎知識|
  
 
next=[[Development/Tutorials/Saving_and_loading (zh TW)|教學 4 - 儲存與載入]]|  
 
next=[[Development/Tutorials/Saving_and_loading (zh TW)|教學 4 - 儲存與載入]]|  
  
reading=無
 
 
}}
 
}}
  
 
==摘要==
 
==摘要==
在本教學中我們將介紹動作(action)的概念。動作是一種提供使用者互動程式的統一方法。
+
在本教學中我們將介紹動作(action)的概念。動作是一種提供使用者互動程式的統一方法。
  
例如,假設我們要為[[Development/Tutorials/Using_KXmlGuiWindow (zh TW)|教學 2]]的使用者提供清除文字區內容的功能,可以是點擊工具列中的按鈕、藉由檔案選單中的選項,或者是通過一個鍵盤快捷鍵。透通過一個{{class|KAction}},就可以實現上述的全部功能。
+
例如,假設我們要為[[Development/Tutorials/Using_KXmlGuiWindow (zh TW)|教學 2]]的使用者提供清除文字區內容的功能,可以是點擊工具列中的按鈕、藉由檔案選單中的選項,或者是通過一個鍵盤快捷鍵。透通過一個 {{class|KAction}},就可以實現上述的全部功能。
  
 
[[image:introtokdetutorial3.png|frame|center]]
 
[[image:introtokdetutorial3.png|frame|center]]
  
 
==KAction==
 
==KAction==
{{class|KAction}} 是一個包含所有動作相關資訊的物件,如圖示、快捷鍵等。你可以將動作連接(connect)到實行運作的 [http://doc.qt.nokia.com/latest/signalsandslots.html slot] 上。
+
{{class|KAction}} 是一個包含所有動作相關資訊的物件,如圖示、快捷鍵等。你可以將動作連接(connect)到實行運作的 [http://doc.qt.nokia.com/latest/signalsandslots.html slot] 上。
  
 
== 程式碼 ==
 
== 程式碼 ==
  
 
===main.cpp===
 
===main.cpp===
<code cppqt>
+
<syntaxhighlight lang="cpp-qt">
 
#include <KApplication>
 
#include <KApplication>
 
#include <KAboutData>
 
#include <KAboutData>
Line 48: Line 47:
 
   return app.exec();
 
   return app.exec();
 
}
 
}
</code>
+
</syntaxhighlight>
這次,<tt>main.cpp</tt>幾乎沒有什麼改動, 只有 KAboutData 建構子裡的參數更新成 tutorial 3了。
+
這次,<tt>main.cpp</tt> 幾乎沒有什麼改動, 只有 KAboutData 建構子裡的參數更新成 tutorial 3了。
  
 
===mainwindow.h===
 
===mainwindow.h===
<code cppqt>
+
<syntaxhighlight lang="cpp-qt">
 
#ifndef MAINWINDOW_H
 
#ifndef MAINWINDOW_H
 
#define MAINWINDOW_H
 
#define MAINWINDOW_H
Line 70: Line 69:
  
 
#endif
 
#endif
</code>
+
</syntaxhighlight>
只增加了函數<tt>void setupActions()</tt>,它負責執行設定 KAction 的全部工作。
+
只增加了函式 <tt>void setupActions()</tt>,它負責執行設定 KAction 的全部工作。
  
 
===mainwindow.cpp===
 
===mainwindow.cpp===
<code cppqt>
+
<syntaxhighlight lang="cpp-qt">
 
#include "mainwindow.h"
 
#include "mainwindow.h"
  
Line 107: Line 106:
 
   setupGUI();
 
   setupGUI();
 
}
 
}
</code>
+
</syntaxhighlight>
  
 
==解釋==
 
==解釋==
 
本教程建立於[[Development/Tutorials/Using_KXmlGuiWindow (zh TW)|教學 2]]中的 KXmlGuiWindow 程式碼。大部分更動都在 <tt>mainwindow.cpp</tt> 裡,其中一個重要的結構改變是,MainWindow 的建構子現在呼叫 <tt>setupActions()</tt> 而不再用 <tt>setupGUI()</tt>。在 <tt>setupActions()</tt> 中包含了新的 KAction 程式碼,並最後自行呼叫 <tt>setupGUI()</tt>。
 
本教程建立於[[Development/Tutorials/Using_KXmlGuiWindow (zh TW)|教學 2]]中的 KXmlGuiWindow 程式碼。大部分更動都在 <tt>mainwindow.cpp</tt> 裡,其中一個重要的結構改變是,MainWindow 的建構子現在呼叫 <tt>setupActions()</tt> 而不再用 <tt>setupGUI()</tt>。在 <tt>setupActions()</tt> 中包含了新的 KAction 程式碼,並最後自行呼叫 <tt>setupGUI()</tt>。
  
=== 創建 KAction 物件===
+
=== 建立 KAction 物件===
我們將透過一系列的步驟來建立 KAction 物件。首先,在程式碼中含入 <tt>KAction</tt> 函式庫並創建 KAction:
+
我們將透過一系列的步驟來建立 KAction 物件。首先,在程式碼中含入 <tt>KAction</tt> 函式庫並建立 KAction:
<code cppqt>
+
<syntaxhighlight lang="cpp-qt">
 
#include <KAction>
 
#include <KAction>
 
...
 
...
 
KAction* clearAction = new KAction(this);
 
KAction* clearAction = new KAction(this);
</code>
+
</syntaxhighlight>
上面這行程式碼創建了一個叫做 <tt>clearAction</tt> 的物件。
+
上面這行程式碼建立了一個叫做 <tt>clearAction</tt> 的物件。
  
 
===設定 KAction 屬性===
 
===設定 KAction 屬性===
 
====文字====
 
====文字====
有了KAction物件之後,我們就可以來設定它的屬性。下面這段程式碼設定了顯示在選單中和工具列圖示下的文字。
+
有了 KAction 物件之後,我們就可以來設定它的屬性。下面這段程式碼設定了顯示在選單中和工具列圖示下的文字。
  
<code cppqt>clearAction->setText(i18n("Clear"));</code>
+
<syntaxhighlight lang="cpp-qt">clearAction->setText(i18n("Clear"));</syntaxhighlight>
  
注意,文字將被 i18n() 函數所處理。這是翻譯 UI 所必須的(更多資訊,可參考[[Development/Tutorials/Localization/i18n|i18n 教學]] )。
+
注意,文字將被 i18n() 函數所處理。這是翻譯 UI 所必須的(更多資訊,可參考[[Development/Tutorials/Localization/i18n|i18n 教學]])。
  
 
====圖示====
 
====圖示====
如果你希望動作能顯示在工具列中,那麼最好給它指定一個圖示。下面的程式碼使用<tt>setIcon()</tt>)函數,將標準KDE的<tt>document-new</tt>圖示設定為動作的圖示:
+
如果你希望動作能顯示在工具列中,那麼最好給它指定一個圖示。下面的程式碼使用<tt>setIcon()</tt> 函式,將 KDE 標準的 <tt>document-new</tt> 圖示設定為動作的圖示:
  
<code cppqt>clearAction->setIcon(KIcon("document-new"));</code>
+
<syntaxhighlight lang="cpp-qt">clearAction->setIcon(KIcon("document-new"));</syntaxhighlight>
  
 
====鍵盤快捷鍵====
 
====鍵盤快捷鍵====
 
設定我們動作的鍵盤快捷鍵很簡單:
 
設定我們動作的鍵盤快捷鍵很簡單:
  
<code cppqt>clearAction->setShortcut(Qt::CTRL + Qt::Key_W);</code>
+
<syntaxhighlight lang="cpp-qt">clearAction->setShortcut(Qt::CTRL + Qt::Key_W);</syntaxhighlight>
  
這會聯結Ctrl+W 到我們的 KAction。
+
這會聯結 Ctrl+W 到我們的 KAction。
  
 
===加入到動作集===
 
===加入到動作集===
為了讓我們的動作能夠被XMLGUI框架訪問(會在後面解釋),必須將它加入到程式的''動作集''(action collectio)中。可以像下面這樣,經由<tt>actionCollection()</tt>函數來訪問動作集:
+
為了讓我們的動作能夠被 XMLGUI 框架訪問(會在後面解釋),必須將它加入到程式的''動作集''(action collectio)中。可以像下面這樣,經由 <tt>actionCollection()</tt> 函數來訪問動作集:
<code cppqt>
+
<syntaxhighlight lang="cpp-qt">
 
actionCollection()->addAction("clear", clearAction);
 
actionCollection()->addAction("clear", clearAction);
</code>
+
</syntaxhighlight>
這裡我們將KAction物件<tt>clearAction</tt>加入了動作集,並將其命名為''clear''。XMLGUI框架會使用這個名稱(''clear'')來引用該動作,因此它不應該是區域的,因為它僅能在內部使用。
+
這裡我們將 KAction 物件<tt>clearAction</tt>加入了動作集,並將其命名為''clear''。XMLGUI框架會使用這個名稱(''clear'')來引用該動作,因此它不應該是區域的,因為它僅能在內部使用。
  
 
====連接動作====
 
====連接動作====
完成對動作的設定之後,接下來我們需要將它連接到實際進行處理的部分。在這裡(因為我們希望清除文字區中的內容)我們將動作連接到KTextEdit的<tt>clear()</tt> 方法 (which, unsurprisingly, clears the KTextEdit)。
+
完成對動作的設定之後,接下來我們需要將它連接到實際進行處理的部分。在這裡(因為我們希望清除文字區中的內容)我們將動作連接到 KTextEdit 的 <tt>clear()</tt> 方法(毫不意外,它會清除 KTextEdit)。
  
<code cppqt>
+
<syntaxhighlight lang="cpp-qt">
 
connect( clearAction, SIGNAL( triggered(bool) ),  
 
connect( clearAction, SIGNAL( triggered(bool) ),  
 
         textArea, SLOT( clear() ) );
 
         textArea, SLOT( clear() ) );
</code>
+
</syntaxhighlight>
  
 
這與 Qt 裡的 {{qt|QAction}} 用法是相同的。
 
這與 Qt 裡的 {{qt|QAction}} 用法是相同的。
Line 160: Line 159:
 
===KStandardAction===
 
===KStandardAction===
  
對於那些幾乎在所有KDE程式中出現的動作,如「離開」(quit)、「儲存」(save)及「載入」(load)等,KDE提供了一些預定義的KAction。可以透過[http://api.kde.org/4.x-api/kdelibs-apidocs/kdeui/html/namespaceKStandardAction.html KStandardAction] 來訪問它們。
+
對於那些幾乎在所有 KDE 程式中出現的動作,如「離開」(quit)、「儲存」(save)及「載入」(load)等,KDE 提供了一些預定義的 KAction。可以透過 [http://api.kde.org/4.x-api/kdelibs-apidocs/kdeui/html/namespaceKStandardAction.html KStandardAction] 來訪問它們。
  
使用它們很簡單。只要含入有關的函式庫(<tt>#include <KStandardAction></tt>)),簡單的將你希望執行的函數和要加入的 KActionCollection 提供給它即可。例如:
+
使用它們很簡單。只要含入有關的函式庫(<tt>#include <KStandardAction></tt>),簡單的將你希望執行的函數和要加入的 KActionCollection 提供給它即可。例如:
  
<code cppqt>KStandardAction::quit(kapp, SLOT(quit()), actionCollection());</code>
+
<syntaxhighlight lang="cpp-qt">KStandardAction::quit(kapp, SLOT(quit()), actionCollection());</syntaxhighlight>
  
這會創建一個帶有正確的圖示、文字和快捷鍵的KAction,並加入檔案選單。
+
這會建立一個帶有正確的圖示、文字和快捷鍵的 KAction,並加入檔案選單。
  
 
==增加動作到選單和工具列==
 
==增加動作到選單和工具列==
現在,新的「Clear」動作已經創建,但還沒有聯結到任何選單或工具列。這需要使用一項叫做 XMLGUI 的 KDE技術來實現,它會為你實現很多很棒的功能諸如可移動的工具列之類。
+
現在,新的「Clear」動作已經建立,但還沒有聯結到任何選單或工具列。這需要使用一項叫做 XMLGUI 的 KDE 技術來實現,它會為你實現很多很棒的功能諸如可移動的工具列之類。
  
{{note|在 KDE4 之後的版本中,XMLGUI 可能會被叫做 liveui 的新框架所取代。不過,目前 XMLGUI 還仍是唯一正確設定 UI 的方法。}}
+
{{note (zh TW)|在 KDE4 之後的版本中,XMLGUI 可能會被叫做 liveui 的新框架所取代。不過,目前 XMLGUI 還仍是唯一正確設定 UI 的方法。}}
  
 
==XMLGUI==
 
==XMLGUI==
  
{{class|KXmlGuiWindow}} 中的 <tt>setupGUI()</tt> 函數依賴 XMLGUI 系統來建構 GUI,XMLGUI 通過解析 XML 格式的介面描述檔來實現這一功能。
+
{{class|KXmlGuiWindow}} <tt>setupGUI()</tt> 函式依賴 XMLGUI 系統來建構 GUI,XMLGUI 通過解析 XML 格式的介面描述檔來實現這一功能。
  
該 XML 檔的命名規範是 <tt>appnameui.rc</tt>,其中 <tt>appname</tt> 是你在{{class|KAboutData}}中設定的名稱(在本例中是''tutorial3'')。因此在我們的例子裡,該檔被命名為<tt>tutorial3ui.rc</tt>,並置於 build 目錄。這個檔案具體放在何處,是由 CMake 來處理的。
+
該 XML 檔的命名規範是 <tt>appnameui.rc</tt>,其中 <tt>appname</tt> 是你在 {{class|KAboutData}} 中設定的名稱(在本例是 ''tutorial3'')。因此在我們的例子裡,該檔被命名為<tt>tutorial3ui.rc</tt>,並置於 build 目錄。這個檔案具體放在何處,是由 CMake 來處理的。
  
 
''另見'':[http://developer.kde.org/documentation/library/kdeqt/kde3arch/xmlgui.html developer.kde.org] 仍然提供 KDE4 的有效的資訊。
 
''另見'':[http://developer.kde.org/documentation/library/kdeqt/kde3arch/xmlgui.html developer.kde.org] 仍然提供 KDE4 的有效的資訊。
Line 183: Line 182:
 
==''appname''ui.rc 檔案==
 
==''appname''ui.rc 檔案==
  
因為 UI 的描述是用 XML 來定義的,因此其排版必須嚴格遵守規範。本教學中不會深入討論這一主題,不過可以訪問[[Development/Architecture/KDE4/XMLGUI_Technology|詳細的 XMLGUI 頁面]]以獲取更多資訊([http://developer.kde.org/documentation/tutorials/xmlui/preface.html 這裡]還有一個舊的教學)。
+
因為 UI 的描述是用 XML 來定義的,因此其排版必須嚴格遵守規範。本教學中不會深入討論這一主題,不過可以訪問[[Development/Architecture/KDE4/XMLGUI_Technology|詳細的 XMLGUI 頁面]]以獲取更多資訊([http://developer.kde.org/documentation/tutorials/xmlui/preface.html 這裡]還有一個舊的教學)。
  
 
===tutorial3ui.rc===
 
===tutorial3ui.rc===
<code xml>
+
<syntaxhighlight lang="xml">
 
<?xml version="1.0" encoding="UTF-8"?>
 
<?xml version="1.0" encoding="UTF-8"?>
 
<gui name="tutorial3"
 
<gui name="tutorial3"
Line 207: Line 206:
  
 
</gui>
 
</gui>
</code>
+
</syntaxhighlight>
  
<tt><Toolbar></tt> 標籤讓你可以描述工具列(toolbar),即視窗上部包含圖示的長條。這裡它被賦予了一個唯一的名字 ''mainToolBar'' ,並用 <tt><text></tt> 標籤將它的用戶可見名稱設成了 ''Main Toolbar'' 。使用 <tt><Action></tt> 標籤,加入 clear 動作到了工具列中。在此標籤的名稱參數會作為字串傳遞給 <tt>mainwindow.cpp</tt> 中的  KActionCollection 與 <tt>addAction()</tt> 。
+
<tt><Toolbar></tt> 標籤讓你可以描述工具列(toolbar),即視窗上部包含圖示的長條。這裡它被賦予了一個唯一的名字 ''mainToolBar'' ,並用 <tt><text></tt> 標籤將它的用戶可見名稱設成了 ''Main Toolbar'' 。使用 <tt><Action></tt> 標籤,加入 clear 動作到了工具列中。在此標籤的名稱參數會作為字串傳遞給 <tt>mainwindow.cpp</tt> 中的  KActionCollection 與 <tt>addAction()</tt> 。
  
除了在工具列中加入動作外,它也可以被加入到選單列(menubar)中。這裡用與加入工具列同樣的方法,將該動作增加到 <tt>MenuBar</tt> 裡的 ''File'' 選單中。
+
除了在工具列中加入動作外,它也可以被加入到選單列(menubar)中。這裡用與加入工具列同樣的方法,將該動作增加到 <tt>MenuBar</tt> 裡的 ''File'' 選單中。
  
如果你在上次安裝後又對.rc 檔作了更新,那麼需要修改<tt><nowiki><gui></nowiki></tt>標籤中的 'version' 屬性,以強制更新系統快取。確保它是一個整數,如果您使用小數值它會無法運作,而且不會通知它無法運作。'''注意:'''版本屬性必須是一個整數,也就是說,它不能包含小數點或其他非數字,就像應用程式的版本號。
+
如果你在上次安裝後又對.rc 檔作了更新,那麼需要修改 <tt><nowiki><gui></nowiki></tt> 標籤中的 'version' 屬性,以強制更新系統快取。確保它是一個整數,如果您使用小數值它會無法運作,而且不會通知它無法運作。'''注意:'''版本屬性必須是一個整數,也就是說,它不能包含小數點或其他非數字,就像應用程式的版本號。
  
程式碼和 .rc檔之間交互作用的一些注意事項:選單自動出現,應該有一個<tt><nowiki><text/></nowiki></tt> 子標籤,除非他們指的是標準選單。動作需要手動創建並使用 .rc檔中的名稱插入到 actionCollection() 。動作可以隱藏或禁用,而選單不能。
+
程式碼和 .rc 檔之間交互作用的一些注意事項:選單自動出現,應該有一個<tt><nowiki><text/></nowiki></tt> 子標籤,除非他們指的是標準選單。動作需要手動建立並使用 .rc檔中的名稱插入到 actionCollection() 。動作可以隱藏或禁用,而選單不能。
  
 
==CMake==
 
==CMake==
  
最後,需要將 <tt>tutorial3ui.rc</tt>  檔放到 KDE 可以找到的地方(不可以僅將它放到源目錄中!)。這意味著需要將專案安裝到某個地方 '''。
+
最後,需要將 <tt>tutorial3ui.rc</tt>  檔放到 KDE 可以找到的地方(不可以僅將它放到原始碼目錄中!)。這意味著需要將專案安裝到某個地方 '''。
  
 
===CMakeLists.txt===
 
===CMakeLists.txt===
<code ini>
+
<syntaxhighlight lang="cmake">
 
project(tutorial3)
 
project(tutorial3)
  
Line 240: Line 239:
 
install(FILES tutorial3ui.rc  
 
install(FILES tutorial3ui.rc  
 
         DESTINATION  ${DATA_INSTALL_DIR}/tutorial3)
 
         DESTINATION  ${DATA_INSTALL_DIR}/tutorial3)
</code>
+
</syntaxhighlight>
  
 
這個檔案幾乎與教學2裡的相同,除了最後多出兩行來描述檔案將被安裝到何處。首先, <tt>tutorial3</tt> 目標被安裝到 <tt>BIN_INSTALL_DIR</tt>;然後描述用戶界面排版的 <tt>tutorial3ui.rc</tt> 檔被安裝到了應用程式的 data 目錄。
 
這個檔案幾乎與教學2裡的相同,除了最後多出兩行來描述檔案將被安裝到何處。首先, <tt>tutorial3</tt> 目標被安裝到 <tt>BIN_INSTALL_DIR</tt>;然後描述用戶界面排版的 <tt>tutorial3ui.rc</tt> 檔被安裝到了應用程式的 data 目錄。
  
===編譯、安裝與運行===
+
===編譯、安裝與執行===
 
如果你沒有 KDE4 安裝目錄的寫入權限,可以將它安裝到你的家目錄下的某個資料夾裡。
 
如果你沒有 KDE4 安裝目錄的寫入權限,可以將它安裝到你的家目錄下的某個資料夾裡。
  
設定 <tt>DCMAKE_INSTALL_PREFIX</tt> 開關項,可以告訴 CMake 將程式安裝到何處。也許你只希望將它安裝到本地的某處進行測試(直接將這些教程安裝到你的KDE目錄裡可能有點傻),因此下面的做法可能比較合適:
+
設定 <tt>DCMAKE_INSTALL_PREFIX</tt> 開關項,可以告訴 CMake 將程式安裝到何處。也許你只希望將它安裝到本地的某處進行測試(直接將這些教學安裝到你的 KDE 目錄裡可能有點傻),因此下面的做法可能比較合適:
  
 
  mkdir build && cd build
 
  mkdir build && cd build
Line 254: Line 253:
 
  $HOME/bin/tutorial3
 
  $HOME/bin/tutorial3
  
這將會在你的使用者家目錄下創建一個結構類似於KDE目錄的目錄,並將可執行檔安裝到{{path|$HOME/bin/tutorial3}} 。
+
這將會在你的使用者家目錄下建立一個結構類似於 KDE 目錄的目錄,並將可執行檔安裝到 {{path|$HOME/bin/tutorial3}} 。
  
 
==繼續前進==
 
==繼續前進==

Latest revision as of 13:26, 23 June 2013

Template:I18n/Language Navigation Bar (zh TW)

Template:TutorialBrowser (zh TW)

摘要

在本教學中我們將介紹動作(action)的概念。動作是一種提供使用者互動程式的統一方法。

例如,假設我們要為教學 2的使用者提供清除文字區內容的功能,可以是點擊工具列中的按鈕、藉由檔案選單中的選項,或者是通過一個鍵盤快捷鍵。透通過一個 KAction,就可以實現上述的全部功能。

Introtokdetutorial3.png

KAction

KAction 是一個包含所有動作相關資訊的物件,如圖示、快捷鍵等。你可以將動作連接(connect)到實行運作的 slot 上。

程式碼

main.cpp

#include <KApplication>
#include <KAboutData>
#include <KCmdLineArgs>

#include "mainwindow.h"

int main (int argc, char *argv[])
{
  KAboutData aboutData( "tutorial3", "tutorial3",
      ki18n("Tutorial 3"), "1.0",
      ki18n("A simple text area using KAction etc."),
      KAboutData::License_GPL,
      ki18n("Copyright (c) 2007 Developer") );
  KCmdLineArgs::init( argc, argv, &aboutData );
  KApplication app;
 
  MainWindow* window = new MainWindow();
  window->show();
  return app.exec();
}

這次,main.cpp 幾乎沒有什麼改動, 只有 KAboutData 建構子裡的參數更新成 tutorial 3了。

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <KXmlGuiWindow>
#include <KTextEdit>

class MainWindow : public KXmlGuiWindow
{
  public:
    MainWindow(QWidget *parent=0);
	
  private:
    KTextEdit* textArea;
    void setupActions();
};

#endif

只增加了函式 void setupActions(),它負責執行設定 KAction 的全部工作。

mainwindow.cpp

#include "mainwindow.h"

#include <KApplication>
#include <KAction>
#include <KLocale>
#include <KActionCollection>
#include <KStandardAction>

MainWindow::MainWindow(QWidget *parent)
    : KXmlGuiWindow(parent)
{
  textArea = new KTextEdit;
  setCentralWidget(textArea);

  setupActions();
}

void MainWindow::setupActions()
{
  KAction* clearAction = new KAction(this);
  clearAction->setText(i18n("Clear"));
  clearAction->setIcon(KIcon("document-new"));
  clearAction->setShortcut(Qt::CTRL + Qt::Key_W);
  actionCollection()->addAction("clear", clearAction);
  connect(clearAction, SIGNAL(triggered(bool)),
          textArea, SLOT(clear()));

  KStandardAction::quit(kapp, SLOT(quit()),
                        actionCollection());

  setupGUI();
}

解釋

本教程建立於教學 2中的 KXmlGuiWindow 程式碼。大部分更動都在 mainwindow.cpp 裡,其中一個重要的結構改變是,MainWindow 的建構子現在呼叫 setupActions() 而不再用 setupGUI()。在 setupActions() 中包含了新的 KAction 程式碼,並最後自行呼叫 setupGUI()

建立 KAction 物件

我們將透過一系列的步驟來建立 KAction 物件。首先,在程式碼中含入 KAction 函式庫並建立 KAction:

#include <KAction>
...
KAction* clearAction = new KAction(this);

上面這行程式碼建立了一個叫做 clearAction 的物件。

設定 KAction 屬性

文字

有了 KAction 物件之後,我們就可以來設定它的屬性。下面這段程式碼設定了顯示在選單中和工具列圖示下的文字。

clearAction->setText(i18n("Clear"));

注意,文字將被 i18n() 函數所處理。這是翻譯 UI 所必須的(更多資訊,可參考i18n 教學)。

圖示

如果你希望動作能顯示在工具列中,那麼最好給它指定一個圖示。下面的程式碼使用setIcon() 函式,將 KDE 標準的 document-new 圖示設定為動作的圖示:

clearAction->setIcon(KIcon("document-new"));

鍵盤快捷鍵

設定我們動作的鍵盤快捷鍵很簡單:

clearAction->setShortcut(Qt::CTRL + Qt::Key_W);

這會聯結 Ctrl+W 到我們的 KAction。

加入到動作集

為了讓我們的動作能夠被 XMLGUI 框架訪問(會在後面解釋),必須將它加入到程式的動作集(action collectio)中。可以像下面這樣,經由 actionCollection() 函數來訪問動作集:

actionCollection()->addAction("clear", clearAction);

這裡我們將 KAction 物件clearAction加入了動作集,並將其命名為clear。XMLGUI框架會使用這個名稱(clear)來引用該動作,因此它不應該是區域的,因為它僅能在內部使用。

連接動作

完成對動作的設定之後,接下來我們需要將它連接到實際進行處理的部分。在這裡(因為我們希望清除文字區中的內容)我們將動作連接到 KTextEdit 的 clear() 方法(毫不意外,它會清除 KTextEdit)。

connect( clearAction, SIGNAL( triggered(bool) ), 
         textArea, SLOT( clear() ) );

這與 Qt 裡的 QAction 用法是相同的。

KStandardAction

對於那些幾乎在所有 KDE 程式中出現的動作,如「離開」(quit)、「儲存」(save)及「載入」(load)等,KDE 提供了一些預定義的 KAction。可以透過 KStandardAction 來訪問它們。

使用它們很簡單。只要含入有關的函式庫(#include <KStandardAction>),簡單的將你希望執行的函數和要加入的 KActionCollection 提供給它即可。例如:

KStandardAction::quit(kapp, SLOT(quit()), actionCollection());

這會建立一個帶有正確的圖示、文字和快捷鍵的 KAction,並加入檔案選單。

增加動作到選單和工具列

現在,新的「Clear」動作已經建立,但還沒有聯結到任何選單或工具列。這需要使用一項叫做 XMLGUI 的 KDE 技術來實現,它會為你實現很多很棒的功能諸如可移動的工具列之類。

Template:Note (zh TW)

XMLGUI

KXmlGuiWindowsetupGUI() 函式依賴 XMLGUI 系統來建構 GUI,XMLGUI 通過解析 XML 格式的介面描述檔來實現這一功能。

該 XML 檔的命名規範是 appnameui.rc,其中 appname 是你在 KAboutData 中設定的名稱(在本例是 tutorial3)。因此在我們的例子裡,該檔被命名為tutorial3ui.rc,並置於 build 目錄。這個檔案具體放在何處,是由 CMake 來處理的。

另見developer.kde.org 仍然提供 KDE4 的有效的資訊。

appnameui.rc 檔案

因為 UI 的描述是用 XML 來定義的,因此其排版必須嚴格遵守規範。本教學中不會深入討論這一主題,不過可以訪問詳細的 XMLGUI 頁面以獲取更多資訊(這裡還有一個舊的教學)。

tutorial3ui.rc

<?xml version="1.0" encoding="UTF-8"?>
<gui name="tutorial3"
     version="1"
     xmlns="http://www.kde.org/standards/kxmlgui/1.0"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://www.kde.org/standards/kxmlgui/1.0
                         http://www.kde.org/standards/kxmlgui/1.0/kxmlgui.xsd" >

  <MenuBar>
    <Menu name="file" >
      <Action name="clear" />
    </Menu>
  </MenuBar>

  <ToolBar name="mainToolBar" >
    <text>Main Toolbar</text>
    <Action name="clear" />
  </ToolBar>

</gui>

<Toolbar> 標籤讓你可以描述工具列(toolbar),即視窗上部包含圖示的長條。這裡它被賦予了一個唯一的名字 mainToolBar ,並用 <text> 標籤將它的用戶可見名稱設成了 Main Toolbar 。使用 <Action> 標籤,加入 clear 動作到了工具列中。在此標籤的名稱參數會作為字串傳遞給 mainwindow.cpp 中的 KActionCollection 與 addAction()

除了在工具列中加入動作外,它也可以被加入到選單列(menubar)中。這裡用與加入工具列同樣的方法,將該動作增加到 MenuBar 裡的 File 選單中。

如果你在上次安裝後又對.rc 檔作了更新,那麼需要修改 <gui> 標籤中的 'version' 屬性,以強制更新系統快取。確保它是一個整數,如果您使用小數值它會無法運作,而且不會通知它無法運作。注意:版本屬性必須是一個整數,也就是說,它不能包含小數點或其他非數字,就像應用程式的版本號。

程式碼和 .rc 檔之間交互作用的一些注意事項:選單自動出現,應該有一個<text/> 子標籤,除非他們指的是標準選單。動作需要手動建立並使用 .rc檔中的名稱插入到 actionCollection() 。動作可以隱藏或禁用,而選單不能。

CMake

最後,需要將 tutorial3ui.rc 檔放到 KDE 可以找到的地方(不可以僅將它放到原始碼目錄中!)。這意味著需要將專案安裝到某個地方

CMakeLists.txt

project(tutorial3)

find_package(KDE4 REQUIRED)
include_directories(${KDE4_INCLUDES})

set(tutorial3_SRCS 
  main.cpp
  mainwindow.cpp
)

kde4_add_executable(tutorial3 ${tutorial3_SRCS})

target_link_libraries(tutorial3 ${KDE4_KDEUI_LIBS})

install(TARGETS tutorial3 DESTINATION ${BIN_INSTALL_DIR})
install(FILES tutorial3ui.rc 
        DESTINATION  ${DATA_INSTALL_DIR}/tutorial3)

這個檔案幾乎與教學2裡的相同,除了最後多出兩行來描述檔案將被安裝到何處。首先, tutorial3 目標被安裝到 BIN_INSTALL_DIR;然後描述用戶界面排版的 tutorial3ui.rc 檔被安裝到了應用程式的 data 目錄。

編譯、安裝與執行

如果你沒有 KDE4 安裝目錄的寫入權限,可以將它安裝到你的家目錄下的某個資料夾裡。

設定 DCMAKE_INSTALL_PREFIX 開關項,可以告訴 CMake 將程式安裝到何處。也許你只希望將它安裝到本地的某處進行測試(直接將這些教學安裝到你的 KDE 目錄裡可能有點傻),因此下面的做法可能比較合適:

mkdir build && cd build
cmake .. -DCMAKE_INSTALL_PREFIX=$HOME
make install
$HOME/bin/tutorial3

這將會在你的使用者家目錄下建立一個結構類似於 KDE 目錄的目錄,並將可執行檔安裝到 $HOME/bin/tutorial3

繼續前進

現在你可以開始學習下一課: 儲存與載入


This page was last edited on 23 June 2013, at 13:26. Content is available under Creative Commons License SA 4.0 unless otherwise noted.
-->