開始第一個Qt Widgets

以下通過編寫一個簡單的記事本程序葛闷,來學(xué)習(xí)如何使用Qt Widgets卫键。
最終效果


最終效果

創(chuàng)建項目

在菜單欄中選擇 文件 > 新建文件或項目递鹉,打開引導(dǎo)窗口 New File or Project

創(chuàng)建項目

New File or Project 窗口中選擇 Application > Qt Widgets Application 后馏鹤,點擊 Choose... 按鈕進入下一步米绕,填寫項目名稱和項目路徑

項目名稱和路徑

點擊 下一步 后垢村,選擇構(gòu)建工具割疾,此處我們選擇 qmake

構(gòu)建工具

點擊 下一步 后,生成項目時的類文件信息嘉栓,此處我們將 Class name 修改為 Notepad宏榕,Base class 這一項選擇繼承哪一個基類,可選擇 QMainWindow侵佃、QWidget麻昼、QDialog

  • QMainWindow - 提供一個有菜單條馋辈、錨接窗口(例如工具條)和一個狀態(tài)條的主應(yīng)用程序窗口抚芦,是最常見的窗口形式,可以作為GUI程序的主窗口首有。
  • QWidget - 是所有用戶界面對象的基類燕垃。所有窗口或者控件都直接或間接繼承自QWidget類。
  • QDialog - 是對話框窗口的基類井联。主要用于短期任務(wù)以及和用戶進行簡要通訊的頂級窗口卜壕。


    類信息

點擊 下一步 后,選擇構(gòu)建套件烙常,在這里我已提前安裝了Qt 5.13.1轴捎,選中即可

kits

最后 下一步 > 完成,項目便創(chuàng)建完成蚕脏。

項目結(jié)構(gòu)

Qt Widgets Application 向?qū)槲覀儎?chuàng)建好初始的項目文件:

  • notepad.pro - 工程文件侦副,用來告訴qmake如何創(chuàng)建Makefile
  • main.cpp - 應(yīng)用程序主源文件,main函數(shù)便寫在該文件中
  • notepad.h - Notepad類的頭文件
  • notepad.cpp - Notepad類的源文件
  • notepad.ui - UI窗體描述文件驼鞭,該文件是一個xml文件

點擊運行按鈕秦驯,啟動一下


第一次運行

設(shè)計界面

創(chuàng)建完項目后,Qt Creator 為我們生成了一個notepad.ui文件挣棕,該文件為UI窗體描述文件译隘。
構(gòu)建應(yīng)用時亲桥,Qt Creator會啟動uic讀取ui文件并創(chuàng)建出一個對應(yīng)的頭文件,本項目中的頭文件是ui_notepad.h固耘。

在開始設(shè)計界面前题篷,先準備好圖片資源。

首先厅目,我們需要添加圖片資源番枚,在當(dāng)前項目目錄/data/study/notepad下創(chuàng)建目錄images并將需要用到的圖片放置在其中。然后切換至編輯模式损敷,在項目名上點擊右鍵選擇 Add New...

新建資源文件

在新建文件對話框中選擇 Qt > Qt Resource File 點擊 Choose...葫笼,進入新建資源文件向?qū)?br>

資源文件位置

填寫資源文件的名稱res,并指定路徑為當(dāng)前項目路徑/data/study/notepad后嗤锉,點擊下一步 > 完成渔欢。
完成資源文件的創(chuàng)建后,在左側(cè)項目瀏覽器中能看到一個名為res.qrc的文件瘟忱,現(xiàn)在我們打開該文件奥额,將圖片添加進去

圖片資源

下面,雙擊 notepad.ui 進入設(shè)計模式访诱。

設(shè)計模式界面

先添加一個文本框垫挨,在左側(cè)選擇 Input Widgets > Text Edit 后拖拽至主窗體中

添加文本框

選中主窗體,點擊工具欄中的 垂直布局 或使用快捷鍵 Ctrl + L

工具欄

文本框垂直布局

雙擊 在這里輸入 触菜,分別輸入 &File&Edit九榔,創(chuàng)建兩個菜單 File 和 Edit。& 符號緊跟著的字母為快捷鍵涡相,故此處 File 菜單快捷是 F哲泊,Edit 菜單快捷鍵是 E。

菜單

為菜單 File 添加子菜單 New催蝗、Open切威、Save、SaveAs丙号、Exit先朦。
為菜單 Edit 添加子菜單 Undo、Redo犬缨、Font喳魏、Copy、Cut怀薛、Paste刺彩。

觀察設(shè)計器底部 Action Editor,這些是菜單的動作

Action Editor

雙擊每個動作,為它們添加圖標(biāo)迂苛,由于我們已經(jīng)將圖片資源加載進來了三热,現(xiàn)在可以在圖標(biāo)一項中使用 選擇資源...

編輯動作

選擇資源

接下來,我們要為記事本添加工具欄三幻。
在菜單與文本框之間的空白處右鍵,并選擇 添加工具欄呐能,下圖中紅色區(qū)域便是添加的工具欄

添加工具欄

Action Editor 中的動作拖拽至工具欄中念搬。

工具欄展示

自此,設(shè)計部分結(jié)束摆出,下面該進行編碼朗徊。

編寫代碼

首先,打開 notepad.h 定義記事本的操作

#ifndef NOTEPAD_H
#define NOTEPAD_H

#include <QMainWindow>

QT_BEGIN_NAMESPACE
namespace Ui { class Notepad; }
QT_END_NAMESPACE

class Notepad : public QMainWindow
{
    Q_OBJECT    // (1)

public:
    Notepad(QWidget *parent = nullptr);
    ~Notepad();

private slots:    // (2)
    void newFile();

    void open();

    void save();

    void saveAs();

    void exit();

    void copy();

    void cut();

    void paste();

    void undo();

    void redo();

    void selectFont();

private:
    Ui::Notepad *ui;
    QString currentFile;
};
#endif // NOTEPAD_H

(1) Q_OBJECT 是Qt中定義的宏偎漫,只有直接或間接繼承 QObject 類才可以使用爷恳,只有使用了該宏才具有信號槽機制。當(dāng)前類 Notepad 繼承自 QMainWindow象踊,而 QMainWindow 繼承自 QWidget 即間接繼承了 QObject温亲,所有我們才能定義槽函數(shù)
(2) 以下從 void newFile()void selectFont() 均為槽函數(shù)

打開 notepad.cpp 實現(xiàn)操作代碼

#include "notepad.h"
#include "ui_notepad.h"

#include <QFileDialog>
#include <QFontDialog>
#include <QMessageBox>
#include <QTextStream>

Notepad::Notepad(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::Notepad)
{
    ui->setupUi(this);
    this->setCentralWidget(ui->textEdit);

    connect(ui->actionNew, &QAction::triggered, this, &Notepad::newFile);    // (1)
    connect(ui->actionOpen, &QAction::triggered, this, &Notepad::open);
    connect(ui->actionSave, &QAction::triggered, this, &Notepad::save);
    connect(ui->actionSaveAs, &QAction::triggered, this, &Notepad::saveAs);
    connect(ui->actionExit, &QAction::triggered, this, &Notepad::exit);
    connect(ui->actionCopy, &QAction::triggered, this, &Notepad::copy);
    connect(ui->actionCut, &QAction::triggered, this, &Notepad::cut);
    connect(ui->actionPaste, &QAction::triggered, this, &Notepad::paste);
    connect(ui->actionUndo, &QAction::triggered, this, &Notepad::undo);
    connect(ui->actionRedo, &QAction::triggered, this, &Notepad::redo);
    connect(ui->actionFont, &QAction::triggered, this, &Notepad::selectFont);
}

Notepad::~Notepad()
{
    delete ui;
}

void Notepad::newFile()
{
    currentFile.clear();
    ui->textEdit->setText(QString());
}

void Notepad::open()
{
    QString fileName = QFileDialog::getOpenFileName(this, "打開文件");
    if (fileName.isEmpty()) {
        return;
    }
    QFile file(fileName);
    currentFile = fileName;
    if (!file.open(QIODevice::ReadOnly | QFile::Text)) {
        QMessageBox::warning(this, "警告", "不能打開: " + file.errorString());
        return;
    }
    setWindowTitle(fileName);
    QTextStream in(&file);
    QString text = in.readAll();
    ui->textEdit->setText(text);
    file.close();
}

void Notepad::save()
{
    QString fileName;
    if (currentFile.isEmpty()) {
        fileName = QFileDialog::getSaveFileName(this, "保存");
        currentFile = fileName;
    } else {
        fileName = currentFile;
    }
    QFile file(fileName);
    if (!file.open(QIODevice::WriteOnly | QFile::Text)) {
        QMessageBox::warning(this, "警告", "不能保存: " + file.errorString());
        return;
    }
    setWindowTitle(fileName);
    QTextStream out(&file);
    QString text = ui->textEdit->toPlainText();
    out << text;
    file.close();
}

void Notepad::saveAs()
{
    QString fileName = QFileDialog::getSaveFileName(this, "另存為...");
    QFile file(fileName);

    if (!file.open(QFile::WriteOnly | QFile::Text)) {
        QMessageBox::warning(this, "警告", "不能保存: " + file.errorString());
        return;
    }
    currentFile = fileName;
    setWindowTitle(fileName);
    QTextStream out(&file);
    QString text = ui->textEdit->toPlainText();
    out << text;
    file.close();
}

void Notepad::exit()
{
    QCoreApplication::quit();
}

void Notepad::copy()
{
    ui->textEdit->copy();
}

void Notepad::cut()
{
    ui->textEdit->cut();
}

void Notepad::paste()
{
    ui->textEdit->paste();
}

void Notepad::undo()
{
     ui->textEdit->undo();
}

void Notepad::redo()
{
    ui->textEdit->redo();
}

void Notepad::selectFont()
{
    bool fontSelected;
    QFont font = QFontDialog::getFont(&fontSelected, this);
    if (fontSelected)
        ui->textEdit->setFont(font);
}

(1) 此處是綁定信號,將 New 菜單的 triggered 信號綁定至當(dāng)前類中的 newFile 槽函數(shù)杯矩,當(dāng)點擊了 New 菜單后栈虚,newFile 函數(shù)便會執(zhí)行。

之后史隆,就可以運行了魂务,當(dāng)然,代碼并不健壯泌射,有興趣的可以自己完善一下粘姜。

代碼已上傳至 https://github.com/abeir/qt-study

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市熔酷,隨后出現(xiàn)的幾起案子孤紧,更是在濱河造成了極大的恐慌,老刑警劉巖纯陨,帶你破解...
    沈念sama閱讀 218,036評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件坛芽,死亡現(xiàn)場離奇詭異,居然都是意外死亡翼抠,警方通過查閱死者的電腦和手機咙轩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,046評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來阴颖,“玉大人活喊,你說我怎么就攤上這事×坷ⅲ” “怎么了钾菊?”我有些...
    開封第一講書人閱讀 164,411評論 0 354
  • 文/不壞的土叔 我叫張陵帅矗,是天一觀的道長。 經(jīng)常有香客問我煞烫,道長浑此,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,622評論 1 293
  • 正文 為了忘掉前任滞详,我火速辦了婚禮凛俱,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘料饥。我一直安慰自己蒲犬,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,661評論 6 392
  • 文/花漫 我一把揭開白布岸啡。 她就那樣靜靜地躺著原叮,像睡著了一般。 火紅的嫁衣襯著肌膚如雪巡蘸。 梳的紋絲不亂的頭發(fā)上奋隶,一...
    開封第一講書人閱讀 51,521評論 1 304
  • 那天,我揣著相機與錄音赡若,去河邊找鬼达布。 笑死,一個胖子當(dāng)著我的面吹牛逾冬,可吹牛的內(nèi)容都是我干的黍聂。 我是一名探鬼主播,決...
    沈念sama閱讀 40,288評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼身腻,長吁一口氣:“原來是場噩夢啊……” “哼产还!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起嘀趟,我...
    開封第一講書人閱讀 39,200評論 0 276
  • 序言:老撾萬榮一對情侶失蹤脐区,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后她按,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體牛隅,經(jīng)...
    沈念sama閱讀 45,644評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,837評論 3 336
  • 正文 我和宋清朗相戀三年酌泰,在試婚紗的時候發(fā)現(xiàn)自己被綠了媒佣。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,953評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡陵刹,死狀恐怖默伍,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤也糊,帶...
    沈念sama閱讀 35,673評論 5 346
  • 正文 年R本政府宣布炼蹦,位于F島的核電站,受9級特大地震影響狸剃,放射性物質(zhì)發(fā)生泄漏掐隐。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,281評論 3 329
  • 文/蒙蒙 一钞馁、第九天 我趴在偏房一處隱蔽的房頂上張望瑟枫。 院中可真熱鬧,春花似錦指攒、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,889評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至虑啤,卻和暖如春隙弛,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背狞山。 一陣腳步聲響...
    開封第一講書人閱讀 33,011評論 1 269
  • 我被黑心中介騙來泰國打工全闷, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人萍启。 一個月前我還...
    沈念sama閱讀 48,119評論 3 370
  • 正文 我出身青樓总珠,卻偏偏與公主長得像,于是被迫代替她去往敵國和親勘纯。 傳聞我的和親對象是個殘疾皇子局服,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,901評論 2 355