Archive:Development/Tutorials/KCmdLineArgs (zh TW)

From KDE TechBase
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

Template:I18n/Language Navigation Bar (zh TW)

Template:TutorialBrowser (zh TW)

摘要

現在我們有了一個可以載入和儲存檔案的文字編輯器。我們要讓這個編輯器像其他桌面程式一樣,能用命令列參數開啟檔案,甚至可以在 Dolphin 裡使用開啟方式來開啟檔案。

程式碼

main.cpp

#include <KApplication>
#include <KAboutData>
#include <KCmdLineArgs>
#include <KUrl> //new
 
#include "mainwindow.h"
 
int main (int argc, char *argv[])
{
  KAboutData aboutData( "tutorial5", "tutorial5",
      ki18n("Tutorial 5"), "1.0",
      ki18n("A simple text area which can load and save."),
      KAboutData::License_GPL,
      ki18n("Copyright (c) 2007 Developer") );
  KCmdLineArgs::init( argc, argv, &aboutData );

  KCmdLineOptions options; //新增的
  options.add("+[file]", ki18n("Document to open")); //新增的
  KCmdLineArgs::addCmdLineOptions(options); //新增的

  KApplication app;
 
  MainWindow* window = new MainWindow();
  window->show();

  KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); //新增的
  if(args->count()) //新增的
  {
    window->openFile(args->url(0).url()); //新增的
  }

  return app.exec();
}

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
 
#include <KXmlGuiWindow>
#include <KTextEdit>
 
class MainWindow : public KXmlGuiWindow
{
  Q_OBJECT
  
  public:
    MainWindow(QWidget *parent=0);
    void openFile(const QString &inputFileName); //新增的
  
  private:
    KTextEdit* textArea;
    void setupActions();
    QString fileName;
 
  private slots:
    void newFile();
    void openFile();
    void saveFile();
    void saveFileAs();
    void saveFileAs(const QString &outputFileName);
};
 
#endif

mainwindow.cpp

#include "mainwindow.h"
 
#include <KApplication>
#include <KAction>
#include <KLocale>
#include <KActionCollection>
#include <KStandardAction>
#include <KFileDialog>
#include <KMessageBox>
#include <KIO/NetAccess>
#include <KSaveFile>
#include <QTextStream>
 
MainWindow::MainWindow(QWidget *parent)
    : KXmlGuiWindow(parent),
      fileName(QString())
{
  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());
 
  KStandardAction::open(this, SLOT(openFile()),
                        actionCollection());
 
  KStandardAction::save(this, SLOT(saveFile()),
                        actionCollection());
 
  KStandardAction::saveAs(this, SLOT(saveFileAs()),
                        actionCollection());
 
  KStandardAction::openNew(this, SLOT(newFile()),
                        actionCollection());
 
  setupGUI();
}
 
void MainWindow::newFile()
{
  fileName.clear();
  textArea->clear();
}
 
void MainWindow::saveFileAs(const QString &outputFileName)
{
  KSaveFile file(outputFileName);
  file.open();
  
  QByteArray outputByteArray;
  outputByteArray.append(textArea->toPlainText());
  file.write(outputByteArray);
  file.finalize();
  file.close();
  
  fileName = outputFileName;
}
 
void MainWindow::saveFileAs()
{
  saveFileAs(KFileDialog::getSaveFileName());
}
 
void MainWindow::saveFile()
{
  if(!fileName.isEmpty())
  {
    saveFileAs(fileName);
  }
  else
  {
    saveFileAs();
  }
}
 
void MainWindow::openFile() //變更
{
  openFile(KFileDialog::getOpenFileName());
}

void MainWindow::openFile(const QString &inputFileName) //新增的
{
  QString tmpFile;
  if(KIO::NetAccess::download(inputFileName, tmpFile, 
         this))
  {
    QFile file(tmpFile);
    file.open(QIODevice::ReadOnly);
    textArea->setPlainText(QTextStream(&file).readAll());
    fileName = inputFileName;
 
    KIO::NetAccess::removeTempFile(tmpFile);
  }
  else
  {
    KMessageBox::error(this, 
        KIO::NetAccess::lastErrorString());
  }
}

tutorial5ui.rc

<?xml version="1.0" encoding="UTF-8"?>
<gui name="tutorial5"
     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>

這和前兩個教學的 tutorialxui.rc 一樣,唯一的改變就是從 tutorialx 變成了tutorial5

解釋

mainwindow.h

這裡我們只新增 openFile 函式,它接受一個 QString 作為參數。

void openFile(const QString &inputFileName);

mainwindow.cpp

這部分沒有新增程式碼,只是重新整理一下而已。所有 void openFile() 裡的東西都被移到了 void openFile(const QString &inputFileName) 裡,除了 KFileDialog::getOpenFileName() 的呼叫。

這樣,如果我們要一個對話框就呼叫 openFile(),如果已經有檔案名稱,呼叫openFile(QString) 就可以了。

main.cpp

This is where all the KCmdLineArgs magic happens.

編譯、安裝與執行

CMakeLists.txt

project(tutorial5)
 
find_package(KDE4 REQUIRED)
include_directories( ${KDE4_INCLUDES} )
 
set(tutorial5_SRCS 
  main.cpp
  mainwindow.cpp
)
 
kde4_add_executable(tutorial5 ${tutorial5_SRCS})
 
target_link_libraries(tutorial5 ${KDE4_KDEUI_LIBS}
                                ${KDE4_KIO_LIBS})
 
install(TARGETS tutorial5 DESTINATION ${BIN_INSTALL_DIR})
install( FILES tutorial5ui.rc 
         DESTINATION  ${DATA_INSTALL_DIR}/tutorial5 )

有了這個檔案,這個教學就可以像教學3和4一樣建構和執行了。更多資訊,請見教學3。

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

繼續前進

現在你可以開始學習下一課:### (TODO User:milliams) 教學。