【文本編輯器】二、文件操作功能(上)

2021-03-02 Qt 學習

上一篇開發了文本編輯器界面,在這一篇以及接下來的幾篇中,將對文本編輯器界面開發過程中涉及的所有動作集對應的功能項進行設計。本篇對文本編輯器的窗口標題設置、文件保存和關閉程序時的保存提醒功能進行講解。此外,還包括過QTextEdit類、標準文件對話框和消息框的相關使用。

本篇目錄

1. 設置窗口標題
2. 保存文件
3. 關閉程序時的保存提醒

運行環境:

    win 10 + Qt 5.12.5 + Qt Creator 4.10

1. 設置窗口標題

在《【文本編輯器】一、界面設計》中通過setWindowTitle(tr("文本編輯器"));設置窗口標題,不過這只是應用程式的名稱。常見軟體的標題條通常設置成「文件名 - 軟體名」的形式,下面將按照這一標題形式設置文本編輯器的窗口標題。

在 "textedit.h" 文件中添加設置文本編輯器標題的函數和標題變量的聲明,代碼如下:

1private:
2    void setCurrentFileName(const QString &fileName); // 設置當前文件標題
3    QString fileName; // 當前文件標題名

在源文件中添加函數setCurrentFileName()的實現

1void TextEdit::setCurrentFileName(const QString &fileName)
2{
3    this->fileName = fileName; // 當前文檔名
4    textEdit->document()->setModified(false); // 默認文檔未被修改
5
6    QString shownName; // 標題條顯示的文檔名
7    if (fileName.isEmpty())
8        shownName = "未命名.txt";
9    else
10        shownName = QFileInfo(fileName).fileName();
11 // 設置窗口標題,當文檔被修改後使用星號 '*' 標記
12    setWindowTitle(tr("%1[*] - %2").arg(shownName, tr("文本編輯器")));
13    setWindowModified(false); // 默認標題中不顯示星號*
14}

上面的代碼中,textEdit->document()->setModified()用於設置文檔是否修改過,一般用於關閉時提示保存。QFileInfo(fileName).fileName()用於從文件路徑中提取文件名,這裡使用了QFileInfo類,需要添加頭文件

在構造函數中添加setCurrentFileName(QString())函數,創建窗口初始標題

1setCurrentFileName(QString());

運行程序後的效果如下

此時在文本編輯器中隨意輸入一些文字,窗口標題並沒有如期出現星號 '*' 標記,在構造函數中再加上如下代碼

1connect(textEdit->document(), &QTextDocument::modificationChanged,
2        this, &QWidget::setWindowModified);

用來連接文本編輯窗口和窗口標題,文本編輯窗口的內容被更改時,使用QTextEdit類的document()函數獲取QTextDocument類對象,發出文檔被修改信號函數modificationChanged()。然後使用setWindowModified()函數設置窗口的更改狀態標誌(星號 『*』),如果參數為true,則在標題中設置了星號 '[*]' 標誌的地方顯示 '*' 號,表示該文件已被修改。運行程序後效果如下

2. 保存文件

保存文件功能分為『保存』或『另存為』兩種操作,在 "textedit.h" 文件中添加函數聲明:

1private slots:
2    bool fileSave();
3    bool fileSaveAs();

在對應的源文件中添加頭文件

1#include <QFileDialog>
2#include <QTextDocumentWriter>

文件保存的邏輯是先通過文件名判斷文件是否符合保存的條件,符合則將文件保存至原路徑下,否則則執行『另存為』操作。下面是保存函數的代碼:

1bool TextEdit::fileSave()
2{
3    // 若未命名文件名或文件名者以 ':/' 開頭,則直接執行另存為操作
4    if (fileName.isEmpty())
5        return fileSaveAs();
6    if (fileName.startsWith(QStringLiteral(":/")))
7        return fileSaveAs();
8
9    QTextDocumentWriter writer(fileName);
10    bool success = writer.write(textEdit->document());
11    // 在狀態欄顯示是否保存成功的提示信息
12    if (success) {
13        textEdit->document()->setModified(false);
14        statusBar()->showMessage(tr("已寫入 \"%1\"")
15                                 .arg(QDir::toNativeSeparators(fileName)));
16    } else {
17        statusBar()->showMessage(tr("未能寫入 \"%1\"")
18                                 .arg(QDir::toNativeSeparators(fileName)));
19    }
20    return success;
21}

代碼中QTextDocumentWriter類提供了與格式無關的接口,用於將QTextDocument寫入文件或其他設備。
QTextDocumentWriter writer(fileName);構造一個QTextDocumentWriter對象,該對象將使用指定的文檔格式寫入名稱為fileName的文件。如果未提供格式,則QTextDocumentWriter將通過檢查fileName的擴展名來檢測文檔格式。

另存為函數的實現流程是:新建保存形式的標準文件對話框;設置保存時默認的文件名後綴;將選擇的另存為路徑名賦給窗口標題設置函數。另存為函數的代碼如下:

1bool TextEdit::fileSaveAs()
2{
3    QFileDialog fileDialog(this, tr("另存為...")); // 新建標準文件對話框
4    fileDialog.setAcceptMode(QFileDialog::AcceptSave);
5    QStringList mimeTypes;
6    mimeTypes << "application/vnd.oasis.opendocument.text" << "text/html" << "text/plain";
7    fileDialog.setMimeTypeFilters(mimeTypes); // 從 MIME 類型列表中設置文件對話框中使用的過濾器
8    fileDialog.setDefaultSuffix("odt");       // 如果未指定其他後綴,則將此後綴添加到文件名中
9    if (fileDialog.exec() != QDialog::Accepted)
10        return false;
11    const QString fn = fileDialog.selectedFiles().first(); // 包含對話框中所選文件的絕對路徑的第一個字符串
12    setCurrentFileName(fn);
13    return fileSave();
14}

函數fileDialog.setAcceptMode()設置對話框模式,主要有兩種

Constant
Value
QFileDialog::AcceptOpen
0
QFileDialog::AcceptSave
1

分別表示打開對話框和保存對話框,默認為AcceptOpen模式。取消setupFileActions()函數中對『保存』和『另存為』動作的連接函數connect()的注釋

1void TextEdit::setupFileActions()
2{
3    // 文件主菜單動作集
4    ...
5    connect(actionSave, &QAction::triggered, this, &TextEdit::fileSave);
6    ...
7    connect(actionSaveAs, &QAction::triggered, this, &TextEdit::fileSaveAs);
8    ...
9}

運行程序,點擊『保存』或『另存為』或使用快捷鍵 "Ctrl+S",效果如下

3. 關閉程序時的保存提醒

為了在關閉或退出應用程式時主動提醒用戶保存,還需要設計「關閉」事件的關閉邏輯。這裡通過一個maybeSave()函數來實現,在 "textedit.h" 文件中

1private:
2    bool maybeSave();

函數maybeSave()先判定文檔是否被修改過,若未被修改過則直接退出,否則彈出保存提示對話框,再根據用戶在對話框中的選擇判斷是否保存文件。函數的實現代碼如下:

1bool TextEdit::maybeSave()
2{
3    if (!textEdit->document()->isModified())
4        return true;
5    // 保存提醒消息框
6    const QMessageBox::StandardButton ret =
7        QMessageBox::warning(this, tr("文本編輯器"),
8                             tr("文檔已被修改,是否將其保存?"),
9                             QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
10    // 根據對話框中的選擇判斷是否保存文件
11    if (ret == QMessageBox::Save)
12        return fileSave();
13    else if (ret == QMessageBox::Cancel)
14        return false;
15    return true;
16}

這裡還需要添加相關的頭文件

1#include <QCloseEvent>
2#include <QMessageBox>

在函數maybeSave()基礎上就可以設計「關閉」事件,若maybeSave()函數返回值為真,則關閉文本編輯器,否則就忽略該事件。在 "textedit.h" 文件中聲明關閉函數:

1protected:
2    void closeEvent(QCloseEvent *e) override;

實現代碼如下:

1void TextEdit::closeEvent(QCloseEvent *e)
2{
3    if (maybeSave())
4        e->accept();
5    else
6        e->ignore();
7}

此外,將「文件」菜單中退出動作通過連接函數connect()關聯到窗口關閉槽函數上,代碼如下

1connect(actionQuit, &QAction::triggered, this, &QWidget::close);

運行程序,在文本編輯器中輸入任意內容,然後點擊右上角的關閉或者依次單擊『文件』『退出』,或者使用快捷鍵 "Ctrl+Q",將會提示關閉提醒消息框,效果如下

小結

本篇介紹了文本編輯器的窗口標題設置、文件保存(另存為)和關閉/退出程序時的保存提醒功能,

相關閱讀:

《【文本編輯器】一、界面設計》

《主要的窗體類和主窗體構成》

《Qt 模塊簡介》

《信號與槽》

《代碼化 UI 設計》


相關焦點

  • 【乾貨】大數據文本文件——編輯器的選擇
    無論是測序或者晶片,還是生物信息軟體產生的大量數據,本質上都是文本,這也是近幾年Perl語言在生物信息學領域被大量運用的原因。那麼對於生物大數據,尤其是後期的數據分析及挖掘來說,文本的編輯工作也就貫穿於數據分析的每個階段。
  • 非常好用的文本編輯器 —— Atom
    上一次我們介紹了純文本和富文本,總的來說只要記住一個結論,在開發編寫代碼時,我們應該使用像記事本這樣的純文本編輯器,而不是word這種富文本編輯器
  • 所見即所得,網站頁面的文本編輯器
    與其他文本編輯器相比,「所見即所得」 文本編輯器非常友好。它指已操作的軟體或應用程式所擁有的功能,以及它們具有的許多其他功能。在使用中,此文本編輯器不需要像其他文本編輯器中那樣編寫語法,因為它配備了圖標,只需要單擊將要使用並自動格式化的圖標之一即可。
  • 初識Vi 文本編輯器 | Linux 中國
    如果在你的系統中沒有找到.vimrc文件,那麼 Vim 就會以 Vi 兼容模式啟動(也可以用-C選項強制啟動該模式)。如果你想使用 gVim 以擁有一個圖形用戶界面(GUI),你可以從桌面的應用程式菜單中啟動它。  如果你是一個剛剛學習 Vi 的新用戶,使用圖形用戶界面是一個很好的方法,可以在你可能期望的文本編輯器的行為和 Vi 的設計行為之間提供一個緩衝帶。
  • 【技巧】虹吸墨批量處理文本常見操作
    普通的文本編輯器,只能進行簡單的文字編輯操作,而其實除了文本處理,經常我們還需要對文本文件進行分割合併、批量改名、文件加密、文本計算等處理,往往需要啟用多個第三方軟體。今天則介紹給大家一款高級文本編輯器——虹吸墨,它除了基本的文字處理之外,常見文本文件的處理工作也能一併完成。
  • 專業文件編輯器 IDM UltraEdit v28.0.0.86 中文綠色版
    UltraEdit 被稱作是世界上最好的專業文本編輯/十六進位編輯器。
  • NoteApp for mac(極簡文本編輯器)
    NoteApp for mac是一個極簡主義的文本編輯器,僅適用於TXT格式,因此沒有格式選項,將所有內容保持為純文本格式,NoteApp允許您在全屏模式下工作以幫助您集中精力,並為你提供了特殊的全屏和拆分視圖模式NoteApp for mac
  • iceEditor - 極致簡潔的富文本編輯器
    無任何依賴,一個js文件包含富文本編輯器所有功能。介紹iceEditor是一款簡約風格的富文本編輯器,體型十分嬌小,無任何依賴,基於javascript開發的Web富文本編輯器,輕量、簡潔、易用、開源免費,一個少有的全新的設計風格開源編輯器。
  • Linux系列教程(十)——Linux文本編輯器vim
    這樣我們在實際應用中,遇到需要實現某個功能,我們腦海只要能想起來適用於某個命令就行,至於詳細格式我們可以通過查資料。當我們使用的多了,會不知不覺的記住這些命令,這才是正確的學習方法。Linux命令有很多,如果初學者就想全部記住這些命令的詳細格式,會對我們產生很大的學習挫敗性,還沒記完這些命令,或許你已經喪失了學習Linux的熱情了。
  • 嘗試將 Jed 作為你的 Linux 終端文本編輯器|Linux 中國
    ,但 Linux 有大量的開源文本編輯器,我的目標是在 12 月份對其中的 31 個文本編輯器進行一次公平的測試。 在這篇文章中,我將介紹Jed,它是一個基於終端的編輯器,它的特點是有一個方便的下拉菜單,這讓那些剛剛接觸終端編輯器的用戶,以及那些不喜歡記住每個功能的組合鍵的用戶而言變得特別容易。
  • 超強文本編輯器EditPlus簡體中文綠色版|PC軟體
    版本:v5.3.0.3248官方網站:https://www.editplus.com/簡介:ES-Computing EditPlus是一款小巧功能強大的老牌代碼文本編輯器,可處理文本、網頁和程序語言的文字編輯器,也可以將它作為C/Java/Php等語言的簡單IDE調試編輯工具。
  • Markdown編輯器Typora的圖床功能
    1 Typora的用途它是一款Markdom文本編輯器,支持osx、windows、 Linux三個平臺,是一款完全免費的軟體,在業內深受好評。Markdown則是一種純文本編輯排版格式,能幫助我們的雙手只在鍵盤上操作就能完成文章的排版。例如我這篇文章就是採用Markdown語法編輯的,有興趣的小夥伴可以了解一下。
  • Linux 上 10 個最好的 Markdown 編輯器
    AtomAtom 是一個現代的、跨平臺、開源且強大的文本編輯器,它可以運行在 Linux、Windows 和 MAC OS X 等作業系統上。用戶可以在它的基礎上進行定製,刪減修改任何配置文件。它包含了一些非常傑出的特性:內置軟體包管理器智能自動補全功能提供多窗口操作支持查找替換功能包含一個文件系統瀏覽器輕鬆自定義主題開源、高度擴展性的軟體包等
  • 五種JavaScript富文本編輯器,總有一款適合你
    作為此工具的創建者,Froala 編輯器是由開發人員為開發人員設計的。功能強大且豐富的API為開發者提供了廣泛的可能性,其中包含許多優秀代碼示例文檔,這些文檔將幫助用戶在幾分鐘內就能掌握並使用。Froala編輯器的另一個顯著優勢是易於添加新功能。大量易於使用的插件(其中有30多個)無需進行複雜的操作便可添加新功能。
  • ConyEdit,一款跨編輯器的文本編輯器插件
    ConyEdit,一款跨編輯器的文本編輯器插件,當ConyEdit在後臺運行時,即可在Windows上的任何一款文本編輯器或IDE中使用它的命令,如記事本、Notepad++、Eclipse、Sublime Text、Visual Studio、Android Studio、UltraEdit
  • 迅捷CAD編輯器粘貼成塊的操作方法介紹
    今天小千分享一下使用迅捷CAD編輯器完成粘貼成塊的方法,有興趣的夥伴請細看。如果電腦上沒有安裝迅捷CAD編輯器,那可以在瀏覽器上搜索關鍵詞,登錄官網後下載安裝軟體。雙擊圖標打開運行,點擊【打開更多文件】。或者點擊軟體左上角的【文件】按鈕,把需要粘貼成塊操作的CAD文件導入。
  • 學習使用Python創建文本編輯器應用程式!
    朋友們,大家好,這次再次與大家見面,這一次將發表一篇文章,介紹如何使用Python Tkinter創建文本編輯器。Tkinter是一個Python庫,在你想要創建應用程式時非常有用。如何製作此文本編輯器應用程式呢?
  • Linux下vim編輯器的使用小技巧
    如在一臺Linux伺服器上,同時部署了資料庫伺服器、郵件伺服器等等,而且有不同的管理員來維護。此時由於這個配置文件保存在各自的用戶目錄中,只要他們所採用的用戶登錄名不同,為此就不會彼此的幹擾。二、快速取消錯誤的操作。在Linux作業系統中使用vim工具時,如果輸入了錯誤的參數,而又不知道修改之前參數的值,該怎麼辦呢?
  • PDF文件怎麼去除水印?教你用PDF編輯器三秒完成
    PDF文件怎麼去除水印?因為辦公的需要,我們會經常接觸PDF文件,PDF文件的兼容性很高,在電腦中打開不易出現錯誤。如果我們要對PDF文件進行去除水印或其他編輯,就需要用到PDF編輯器了。那麼大家知道PDF編輯器是怎樣使用的嗎?
  • ed 文本編輯器使用筆記
    ,進入程序後除了光標什麼都不會顯示;如果是打開已有文件,那麼會顯示一行文件大小的字節數,然後光標到下一行等待用戶輸入。ed 是基於行的文本編輯器,也就是說同時只能顯示或編輯文件的某一行。和 Vi 類似,存在兩種模式:輸入模式和命令模式。默認打開文件後進入命令模式。既然是基於行的編輯器,那麼 ed 有一個「當前行」的概念,可以使用 n 查看之,會列印出當前所在行號。默認打開文件後自動跳轉至文件末尾(也就是最後一行)。