Development/Tutorials/Saving and loading (fa): Difference between revisions
Neverendingo (talk | contribs) m (Text replace - "<code cppqt>" to "<syntaxhighlight lang="cpp-qt">") |
No edit summary |
||
(5 intermediate revisions by one other user not shown) | |||
Line 1: | Line 1: | ||
{{TutorialBrowser (fa)| | {{TutorialBrowser (fa)| | ||
Line 25: | Line 25: | ||
===main.cpp=== | ===main.cpp=== | ||
<div dir="ltr"> | <div dir="ltr"> | ||
< | <syntaxhighlight lang="cpp-qt" line> | ||
#include <KApplication> | #include <KApplication> | ||
#include <KAboutData> | #include <KAboutData> | ||
Line 48: | Line 48: | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
</div> | </div> | ||
<tt>main.cpp</tt> نسبت به آموزش قبل هیچ تغییری نکرده فقط tutorial3ها به tutorial4 تغییر دادهشدهاند. | <tt>main.cpp</tt> نسبت به آموزش قبل هیچ تغییری نکرده فقط tutorial3ها به tutorial4 تغییر دادهشدهاند. | ||
Line 54: | Line 54: | ||
===mainwindow.h=== | ===mainwindow.h=== | ||
<div dir="ltr"> | <div dir="ltr"> | ||
< | <syntaxhighlight lang="cpp-qt" line> | ||
#ifndef MAINWINDOW_H | #ifndef MAINWINDOW_H | ||
#define MAINWINDOW_H | #define MAINWINDOW_H | ||
Line 82: | Line 82: | ||
#endif | #endif | ||
</ | </syntaxhighlight> | ||
</div> | </div> | ||
از آنجایی که میخواهیم قابلیتهای ذخیره و بازیابی فایلها را به برنامه بیافزاییم، باید توابعی اضافه کنیم که این کارها را برایمان انجام دهند. چون این توابع از طریق مکانیزم [http://doc.trolltech.com/latest/signalsandslots.html signal/slot] مربوط به Qt فراخوانی میشوند، باید آنها را به عنوان slot معرفی کنیم؛ که در سطر ۱۹ همین اتفاق میافتد. به علاوه، چون در این کلاس slot تعریف میکنیم، باید ماکروی [http://doc.trolltech.com/latest/qobject.html#Q_OBJECT <tt>Q_OBJECT</tt>] را به تعریف آن اضافه کنیم. | از آنجایی که میخواهیم قابلیتهای ذخیره و بازیابی فایلها را به برنامه بیافزاییم، باید توابعی اضافه کنیم که این کارها را برایمان انجام دهند. چون این توابع از طریق مکانیزم [http://doc.trolltech.com/latest/signalsandslots.html signal/slot] مربوط به Qt فراخوانی میشوند، باید آنها را به عنوان slot معرفی کنیم؛ که در سطر ۱۹ همین اتفاق میافتد. به علاوه، چون در این کلاس slot تعریف میکنیم، باید ماکروی [http://doc.trolltech.com/latest/qobject.html#Q_OBJECT <tt>Q_OBJECT</tt>] را به تعریف آن اضافه کنیم. | ||
Line 90: | Line 90: | ||
===mainwindow.cpp=== | ===mainwindow.cpp=== | ||
<div dir="ltr"> | <div dir="ltr"> | ||
< | <syntaxhighlight lang="cpp-qt" line> | ||
#include "mainwindow.h" | #include "mainwindow.h" | ||
Line 202: | Line 202: | ||
} | } | ||
} | } | ||
</ | </syntaxhighlight> | ||
</div> | </div> | ||
===tutorial4ui.rc=== | ===tutorial4ui.rc=== | ||
<div dir="ltr"> | <div dir="ltr"> | ||
< | <syntaxhighlight lang="xml" line> | ||
<?xml version="1.0" encoding="UTF-8"?> | <?xml version="1.0" encoding="UTF-8"?> | ||
<gui name="tutorial4" | <gui name="tutorial4" | ||
Line 228: | Line 228: | ||
</gui> | </gui> | ||
</ | </syntaxhighlight> | ||
</div> | </div> | ||
این فایل هم دقیقا مشابه <tt>tutorial3ui.rc</tt> از آموزش ۳ است. تنها نام آن را به tutorial4 تغییر دادهایم. نیازی به هیچگونه اطلاعات اضافی از <tt>KStandardAction</tt>ها در این فایل نیست. جای هر یک از گزینهها در منوها را به طور خودکار KDE تنظیم میکند. | این فایل هم دقیقا مشابه <tt>tutorial3ui.rc</tt> از آموزش ۳ است. تنها نام آن را به tutorial4 تغییر دادهایم. نیازی به هیچگونه اطلاعات اضافی از <tt>KStandardAction</tt>ها در این فایل نیست. جای هر یک از گزینهها در منوها را به طور خودکار KDE تنظیم میکند. | ||
Line 239: | Line 239: | ||
<syntaxhighlight lang="cpp-qt"> | <syntaxhighlight lang="cpp-qt"> | ||
fileName(QString()) | fileName(QString()) | ||
</ | </syntaxhighlight> | ||
</div> | </div> | ||
به تعریف تابع سازندهی <tt>MainWindow</tt> در سطر ۱۶ است. با این کار، اطمینان حاصل میکنیم که <tt>fileName</tt> از همان ابتدا تهی است. | به تعریف تابع سازندهی <tt>MainWindow</tt> در سطر ۱۶ است. با این کار، اطمینان حاصل میکنیم که <tt>fileName</tt> از همان ابتدا تهی است. | ||
Line 256: | Line 256: | ||
textArea->clear(); | textArea->clear(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
</div> | </div> | ||
<tt>fileName.clear()</tt> مقدار متغیر <tt>fileName</tt> را تهی قرار میدهد. این کار، نمودی از این حقیقت است که فایل هنوز بر روی دیسک وجود ندارد. آنگاه <tt>textArea->clear()</tt> کادر متنی وسط پنجره را خالی میکند. این همان تابعی است که به clearAction در آموزش ۳ پیوند زدیم. | <tt>fileName.clear()</tt> مقدار متغیر <tt>fileName</tt> را تهی قرار میدهد. این کار، نمودی از این حقیقت است که فایل هنوز بر روی دیسک وجود ندارد. آنگاه <tt>textArea->clear()</tt> کادر متنی وسط پنجره را خالی میکند. این همان تابعی است که به clearAction در آموزش ۳ پیوند زدیم. | ||
Line 270: | Line 270: | ||
<syntaxhighlight lang="cpp-qt"> | <syntaxhighlight lang="cpp-qt"> | ||
void MainWindow::saveFileAs(const QString &outputFileName) | void MainWindow::saveFileAs(const QString &outputFileName) | ||
</ | </syntaxhighlight> | ||
</div> | </div> | ||
Line 278: | Line 278: | ||
KSaveFile file(outputFileName); | KSaveFile file(outputFileName); | ||
file.open(); | file.open(); | ||
</ | </syntaxhighlight> | ||
</div> | </div> | ||
Line 286: | Line 286: | ||
QByteArray outputByteArray; | QByteArray outputByteArray; | ||
outputByteArray.append(textArea->toPlainText().toUtf8()); | outputByteArray.append(textArea->toPlainText().toUtf8()); | ||
</ | </syntaxhighlight> | ||
</div> | </div> | ||
حالا با استفاده از تابع <tt>KSaveFile::write()</tt>، آرایهی ساخته شده را در فایل مینویسیم. اگر از یک <tt>QFile</tt> استفاده میکردیم، تغییرات بلافاصله در فایل ذخیره میشدند. با این کار، اگر در میانهی نوشتن مشکلی پیش بیاید، فایل خراب میشود. به همین دلیل، <tt>KSaveFile</tt> ابتدا در یک فایل موقتی مینویسد و سپس هنگامی که <tt>KSaveFile::finalize()</tt> را صدا میزنید، تغییرات در فایل واقعی اعمال میشوند. | حالا با استفاده از تابع <tt>KSaveFile::write()</tt>، آرایهی ساخته شده را در فایل مینویسیم. اگر از یک <tt>QFile</tt> استفاده میکردیم، تغییرات بلافاصله در فایل ذخیره میشدند. با این کار، اگر در میانهی نوشتن مشکلی پیش بیاید، فایل خراب میشود. به همین دلیل، <tt>KSaveFile</tt> ابتدا در یک فایل موقتی مینویسد و سپس هنگامی که <tt>KSaveFile::finalize()</tt> را صدا میزنید، تغییرات در فایل واقعی اعمال میشوند. | ||
Line 294: | Line 294: | ||
file.finalize(); | file.finalize(); | ||
file.close(); | file.close(); | ||
</ | </syntaxhighlight> | ||
</div> | </div> | ||
در پایان، مقدار عضو دادهی <tt>fileName</tt> در کلاس <tt>MainWindow</tt> را به نام فایلی که نوشتهها را در آن ذخیره کردیم، تغییر میدهیم. | در پایان، مقدار عضو دادهی <tt>fileName</tt> در کلاس <tt>MainWindow</tt> را به نام فایلی که نوشتهها را در آن ذخیره کردیم، تغییر میدهیم. | ||
Line 300: | Line 300: | ||
<syntaxhighlight lang="cpp-qt"> | <syntaxhighlight lang="cpp-qt"> | ||
fileName = outputFileName; | fileName = outputFileName; | ||
</ | </syntaxhighlight> | ||
</div> | </div> | ||
Line 313: | Line 313: | ||
saveFileAs(KFileDialog::getSaveFileName()); | saveFileAs(KFileDialog::getSaveFileName()); | ||
} | } | ||
</ | </syntaxhighlight> | ||
</div> | </div> | ||
Line 333: | Line 333: | ||
} | } | ||
} | } | ||
</ | </syntaxhighlight> | ||
</div> | </div> | ||
Line 346: | Line 346: | ||
<syntaxhighlight lang="cpp-qt"> | <syntaxhighlight lang="cpp-qt"> | ||
QString fileNameFromDialog = KFileDialog::getOpenFileName(); | QString fileNameFromDialog = KFileDialog::getOpenFileName(); | ||
</ | </syntaxhighlight> | ||
</div> | </div> | ||
Line 353: | Line 353: | ||
<syntaxhighlight lang="cpp-qt"> | <syntaxhighlight lang="cpp-qt"> | ||
KIO::NetAccess::download(fileNameFromDialog, tmpFile, this) | KIO::NetAccess::download(fileNameFromDialog, tmpFile, this) | ||
</ | </syntaxhighlight> | ||
</div> | </div> | ||
اولین آرگومان، نام فایلی است که میخواهیم دریافت کنیم. دومی یک متغیر QString است که پس پایان دریافت، مکان کپی موقت فایل را در خود خواهد داشت. از این به بعد با همین <tt>tmpFile</tt> سر و کار خواهیم داشت. | اولین آرگومان، نام فایلی است که میخواهیم دریافت کنیم. دومی یک متغیر QString است که پس پایان دریافت، مکان کپی موقت فایل را در خود خواهد داشت. از این به بعد با همین <tt>tmpFile</tt> سر و کار خواهیم داشت. | ||
Line 361: | Line 361: | ||
<syntaxhighlight lang="cpp-qt"> | <syntaxhighlight lang="cpp-qt"> | ||
KMessageBox::error(this, KIO::NetAccess::lastErrorString()); | KMessageBox::error(this, KIO::NetAccess::lastErrorString()); | ||
</ | </syntaxhighlight> | ||
</div> | </div> | ||
Line 371: | Line 371: | ||
QFile file(tmpFile); | QFile file(tmpFile); | ||
file.open(QIODevice::ReadOnly); | file.open(QIODevice::ReadOnly); | ||
</ | </syntaxhighlight> | ||
</div> | </div> | ||
Line 379: | Line 379: | ||
<syntaxhighlight lang="cpp-qt"> | <syntaxhighlight lang="cpp-qt"> | ||
textArea->setPlainText(QTextStream(&file).readAll()); | textArea->setPlainText(QTextStream(&file).readAll()); | ||
</ | </syntaxhighlight> | ||
</div> | </div> | ||
Line 386: | Line 386: | ||
<syntaxhighlight lang="cpp-qt"> | <syntaxhighlight lang="cpp-qt"> | ||
fileName = fileNameFromDialog; | fileName = fileNameFromDialog; | ||
</ | </syntaxhighlight> | ||
</div> | </div> | ||
Line 393: | Line 393: | ||
<syntaxhighlight lang="cpp-qt"> | <syntaxhighlight lang="cpp-qt"> | ||
KIO::NetAccess::removeTempFile(tmpFile); | KIO::NetAccess::removeTempFile(tmpFile); | ||
</ | </syntaxhighlight> | ||
</div> | </div> | ||
Line 400: | Line 400: | ||
===CMakeLists.txt=== | ===CMakeLists.txt=== | ||
<div dir="ltr"> | <div dir="ltr"> | ||
< | <syntaxhighlight lang="ini" line> | ||
project(tutorial4) | project(tutorial4) | ||
Line 419: | Line 419: | ||
install(FILES tutorial4ui.rc | install(FILES tutorial4ui.rc | ||
DESTINATION ${DATA_INSTALL_DIR}/tutorial4) | DESTINATION ${DATA_INSTALL_DIR}/tutorial4) | ||
</ | </syntaxhighlight> | ||
</div> | </div> | ||
Line 427: | Line 427: | ||
<div dir="ltr"> | <div dir="ltr"> | ||
< | <syntaxhighlight lang="text"> | ||
mkdir build && cd build | mkdir build && cd build | ||
cmake .. -DCMAKE_INSTALL_PREFIX=$HOME | cmake .. -DCMAKE_INSTALL_PREFIX=$HOME | ||
make install | make install | ||
$HOME/bin/tutorial4 | $HOME/bin/tutorial4 | ||
</ | </syntaxhighlight> | ||
</div> | </div> | ||
Latest revision as of 15:46, 15 July 2012
سری آموزشی | آموزش مقدماتی |
پیشنیازها | آموزش ۳ - KActionها |
پس از این | آموزش ۵ - استفاده از KCmdLineArgs |
مطالعهی بیشتر | KIO::NetAccess QFile |
چکیده
حالا یک ویرایشگر متن ساده داریم، ولی هنوز کار بهدردبخوری انجام نمیدهد. یک ویرایشگر متن باید حداقل بتواند فایلها را از دیسک بخواند، فایلهایی که شما ساخته یا ویراستهاید را ذخیره کند و همینطور فایل جدید بسازد.
KDE برای کار با فایلها کلاسهایی دارد که کار را برای برنامهنویسان بسیار آسان میسازد. کتابخانهی KIO به شما امکان میدهد به سادگی به فایلها دسترسی پیدا کنید. همچنین با کمک KIO میتوانید از کادرهای استاندارد بازکردن و ذخیرهسازی فایلها در برنامهتان استفاده کنید.
کدهای منبع
main.cpp
#include <KApplication>
#include <KAboutData>
#include <KCmdLineArgs>
#include "mainwindow.h"
int main (int argc, char *argv[])
{
KAboutData aboutData( "tutorial4", "tutorial4",
ki18n("Tutorial 4"), "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 );
KApplication app;
MainWindow* window = new MainWindow();
window->show();
return app.exec();
}
main.cpp نسبت به آموزش قبل هیچ تغییری نکرده فقط tutorial3ها به tutorial4 تغییر دادهشدهاند.
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <KXmlGuiWindow>
#include <KTextEdit>
class MainWindow : public KXmlGuiWindow
Q_OBJECT
{
public:
MainWindow(QWidget *parent=0);
private:
KTextEdit* textArea;
void setupActions();
QString fileName; //new
private slots:
void newFile(); //new
void openFile(); //new
void saveFile(); //new
void saveFileAs(); //new
void saveFileAs(const QString &outputFileName); //new
};
#endif
از آنجایی که میخواهیم قابلیتهای ذخیره و بازیابی فایلها را به برنامه بیافزاییم، باید توابعی اضافه کنیم که این کارها را برایمان انجام دهند. چون این توابع از طریق مکانیزم signal/slot مربوط به Qt فراخوانی میشوند، باید آنها را به عنوان slot معرفی کنیم؛ که در سطر ۱۹ همین اتفاق میافتد. به علاوه، چون در این کلاس slot تعریف میکنیم، باید ماکروی Q_OBJECT را به تعریف آن اضافه کنیم.
همچنین در طول برنامه، باید نام فایلی که کاربر باز کردهاست را بدانیم؛ بنابراین متغیر {qt|QString} fileName را اعلان میکنیم.
mainwindow.cpp
#include "mainwindow.h"
#include <KApplication>
#include <KAction>
#include <KLocale>
#include <KActionCollection>
#include <KStandardAction>
#include <KFileDialog> //new
#include <KMessageBox> //new
#include <KIO/NetAccess> //new
#include <KSaveFile> //new
#include <QTextStream> //new
MainWindow::MainWindow(QWidget *parent)
: KXmlGuiWindow(parent),
fileName(QString()) //new
{
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()); //new
KStandardAction::save(this, SLOT(saveFile()),
actionCollection()); //new
KStandardAction::saveAs(this, SLOT(saveFileAs()),
actionCollection()); //new
KStandardAction::openNew(this, SLOT(newFile()),
actionCollection()); //new
setupGUI();
}
//New from here on
void MainWindow::newFile()
{
fileName.clear();
textArea->clear();
}
void MainWindow::saveFileAs(const QString &outputFileName)
{
KSaveFile file(outputFileName);
file.open();
QByteArray outputByteArray;
outputByteArray.append(textArea->toPlainText().toUtf8());
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()
{
QString fileNameFromDialog = KFileDialog::getOpenFileName();
QString tmpFile;
if(KIO::NetAccess::download(fileNameFromDialog, tmpFile,
this))
{
QFile file(tmpFile);
file.open(QIODevice::ReadOnly);
textArea->setPlainText(QTextStream(&file).readAll());
fileName = fileNameFromDialog;
KIO::NetAccess::removeTempFile(tmpFile);
}
else
{
KMessageBox::error(this,
KIO::NetAccess::lastErrorString());
}
}
tutorial4ui.rc
<?xml version="1.0" encoding="UTF-8"?>
<gui name="tutorial4"
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>
این فایل هم دقیقا مشابه tutorial3ui.rc از آموزش ۳ است. تنها نام آن را به tutorial4 تغییر دادهایم. نیازی به هیچگونه اطلاعات اضافی از KStandardActionها در این فایل نیست. جای هر یک از گزینهها در منوها را به طور خودکار KDE تنظیم میکند.
شرح
خوب. پس میخواهیم برنامهای بنویسم که ذخیره و بازیابی انجام دهد. این کار در mainwindow.cpp اتفاق میافتد.
نخستین کاری که انجام میدهیم، اضافهکردن
fileName(QString())
به تعریف تابع سازندهی MainWindow در سطر ۱۶ است. با این کار، اطمینان حاصل میکنیم که fileName از همان ابتدا تهی است.
افزودن actionها
در اینجا، ارائهی یک رابط بیرونی به کاربران برنامه، اولین کاری خواهد بود که میخواهیم انجام دهیم. رابط کاربر برنامه به کاربران اجازه میدهد به برنامه بگویند فایل را باز کن، ذخیره کن یا فایل جدیدی بساز. به مانند گزینهی quit در آموزش ۳، از KStandardActionها استفاده میکنیم. در طول سطرهای ۳۷ تا ۴۷ actionهای جدید را به منو اضافه میکنیم و هر کدام را به slot مناسبی که در فایل سرایند تعریف کردهایم، پیوند میدهیم.
ساختن یک فایل جدید
اولین تابعی که مینویسیم، تابع newFile() است.
void MainWindow::newFile()
{
fileName.clear();
textArea->clear();
}
fileName.clear() مقدار متغیر fileName را تهی قرار میدهد. این کار، نمودی از این حقیقت است که فایل هنوز بر روی دیسک وجود ندارد. آنگاه textArea->clear() کادر متنی وسط پنجره را خالی میکند. این همان تابعی است که به clearAction در آموزش ۳ پیوند زدیم.
ذخیرهکردن یک فایل
saveFileAs(QString)
حالا میخواهیم اولین کدی که با فایلها سر و کار دارد، بنویسیم. میخواهیم تابعی پیادهسازی کنیم که نوشتههای درون کادر متن را در یک فایل، با نامی که به عنوان پارامتر رد میکنیم، ذخیره کند. KDE کلاسی در اختیار ما میگذارد که به کمک آن بتوانیم با اطمینان فایلی را ذخیره کنیم. این کلاس KSaveFile نام دارد و از کلاس QFile متعلق به Qt مشتق شده است.
اعلان تابع به این صورت است:
void MainWindow::saveFileAs(const QString &outputFileName)
سپس شیء KSaveFile خود را میسازیم و باز میکنیم:
KSaveFile file(outputFileName);
file.open();
حالا که فایلمان باز شده و آمادهی نوشتن است، باید نوشتههای درون کادر متنی را به قالبی درآوریم که بتوان آن را در فایل نوشت. برای این کار، یک QByteArray میسازیم و آن را با متن سادهی درون کادر متن پر میکنیم:
QByteArray outputByteArray;
outputByteArray.append(textArea->toPlainText().toUtf8());
حالا با استفاده از تابع KSaveFile::write()، آرایهی ساخته شده را در فایل مینویسیم. اگر از یک QFile استفاده میکردیم، تغییرات بلافاصله در فایل ذخیره میشدند. با این کار، اگر در میانهی نوشتن مشکلی پیش بیاید، فایل خراب میشود. به همین دلیل، KSaveFile ابتدا در یک فایل موقتی مینویسد و سپس هنگامی که KSaveFile::finalize() را صدا میزنید، تغییرات در فایل واقعی اعمال میشوند.
file.write(outputByteArray);
file.finalize();
file.close();
در پایان، مقدار عضو دادهی fileName در کلاس MainWindow را به نام فایلی که نوشتهها را در آن ذخیره کردیم، تغییر میدهیم.
fileName = outputFileName;
saveFileAs()
این تابعی است که اسلات saveAs به آن پیوند خوردهاست. این تابع تنها تابع عمومی saveFileAs(QString) را با مقدار برگشتی تابع KFileDialog::getSaveFileName() به عنوان آرگومان فرا میخواند.
void MainWindow::saveFileAs()
{
saveFileAs(KFileDialog::getSaveFileName());
}
این اولین استفادهی واقعی ما از کتابخانهی KIO است. KFileDialog تعدادی تابع استاتیک در اختیار ما میگذارد تا بتوانیم کادرهای محاورهای عمومی فایل (یعنی همان کادرهای Open/Save File) را نمایش دهیم. با فراخوانی KFileDialog::getSaveFileName()، پنجرهای باز میشود که از آنجا کاربر میتواند برای فایل خود نامی برگزیند. تابع نام کامل فایل (همراه با مسیر ذخیرهسازی) برمیگرداند. این مقدار بازگشتی، سپس، به تابع saveFileAs(QString) رد میشود.
saveFile()
void MainWindow::saveFile()
{
if(!fileName.isEmpty())
{
saveFileAs(fileName);
}
else
{
saveFileAs();
}
}
در این تابع چیز چندان جالب توجهی وجود ندارد؛ فقط منقطی که بر اساس آن تصمیم بگیریم پنجرهی ذخیرهی فایل را نمایش بدهیم یا نه. اگر fileName خالی نباشد، در این صورت فایل با همان نام fileName ذخیره خواهد شد. در غیر این صورت پنجرهی ذخیرهی فایل برای کاربر به نمایش در میآید تا بتواند نامی انتخاب کند.
بازکردن یک فایل
در پایان، باید به برنامه قابلیت بازیابی فایلها بدهیم. همهی کد این کار در تابع MainWindow::openFile() قرار گرفته است.
اول باید از کاربر بپرسیم نام فایلی که میخواهد باز کند چیست. این کار را با استفاده از تابع دیگری از KFileDialog انجام میدهیم؛ این بار getOpenFileName():
QString fileNameFromDialog = KFileDialog::getOpenFileName();
حالا از کتابخانهی KIO استفاده میکنیم تا فایل را دریافت کنیم. KIO به ما امکان میدهد فایل را به صورت یک QFile دریافت کنیم؛ حتی اگر فایل در یک ارتباط راه دور مانند یک FTP قرار داشته باشد. تابع download از NetAccess را به صورت زیر فرا میخوانیم:
KIO::NetAccess::download(fileNameFromDialog, tmpFile, this)
اولین آرگومان، نام فایلی است که میخواهیم دریافت کنیم. دومی یک متغیر QString است که پس پایان دریافت، مکان کپی موقت فایل را در خود خواهد داشت. از این به بعد با همین tmpFile سر و کار خواهیم داشت.
خروجی تابع، بسته به موفقیت آمیز بودن یا نبودن عملیات، true یا false خواهد بود. اگر عملیات با شکست مواجه شد، پیامی حاوی خطای رخ داده نمایش میدهیم:
KMessageBox::error(this, KIO::NetAccess::lastErrorString());
در غیر این صورت، به باز کردن فایل ادامه میدهیم.
یک QFile میسازیم و فایل موقتی که NetAccess::download() ساخته را به تابع سازندهاش رد میکنیم. همچنین مشخص میکنیم که فایل به صورت «فقط خواندنی» باز شود.
QFile file(tmpFile);
file.open(QIODevice::ReadOnly);
برای نمایش محتویات فایل، باید از یک QTextStream استفاده کنیم. با رد کردن اشارهگر file به تابع سازندهی QTextStream یک نمونه میسازیم و سپس تابع readAll() آن را فراخوانی میکنیم تا نوشتهها را از فایل بخوانیم. سپس آن را به تابع setPlainText() مربوط به کادر متنی رد میکنیم.
textArea->setPlainText(QTextStream(&file).readAll());
سپس مسیر فایل بازشده را در fileName نگهداری میکنیم:
fileName = fileNameFromDialog;
و نهایتا فایل موقتی که NetAccess::download() ساخته است را پاک میکنیم:
KIO::NetAccess::removeTempFile(tmpFile);
ساخت، نصب و اجرا
CMakeLists.txt
project(tutorial4)
find_package(KDE4 REQUIRED)
include_directories(${KDE4_INCLUDES})
set(tutorial4_SRCS
main.cpp
mainwindow.cpp
)
kde4_add_executable(tutorial4 ${tutorial4_SRCS})
target_link_libraries(tutorial4 ${KDE4_KDEUI_LIBS}
${KDE4_KIO_LIBS})
install(TARGETS tutorial4 DESTINATION ${BIN_INSTALL_DIR})
install(FILES tutorial4ui.rc
DESTINATION ${DATA_INSTALL_DIR}/tutorial4)
چون حالا از کتابخانهی KIO استفاده میکنیم، باید به CMake بگوییم آن را هم با برنامهمان لینک کند. این کار را با رد کردن ${KDE4_KIO_LIBS} به تابع target_link_libraries() انجام میدهیم.
با این فایل، میتوانید برنامه را درست مانند آموزش ۳ بسازید. برای اطلاعات بیشتر، به آموزش ۳ مراجعه کنید.
mkdir build && cd build
cmake .. -DCMAKE_INSTALL_PREFIX=$HOME
make install
$HOME/bin/tutorial4
به پیش
حالا میتوانید به سوی آموزش KCmdLineArgs پیش بروید.