2020年5月25日 星期一

TextEdit 的基本應用

TextEdit 的基本應用

前言

  在上一篇 Qt 的拖拉 widget 與事件 中,提及了 PushButton 的基本應用,這次來使用 TextEdit 來做為輸入,在此做個紀錄。

內容

  先到 [ GitLab ] HelloQt 下載範例,這次應用的專案路徑
(HelloQt' directory)/TextEdit/Basic,在 Qt Creator 開啟設計介面會看到以下
TextEdit 在 widget 工具箱的位置

圖中可以看到 TextEdit 在 widget 工具箱的位置,範例已經拖好了一個,可以依據需要自己新增。範例執行的結果如下
範例的執行結果

在範例按下"ShowMsg"後,會在 debug 訊息視窗顯示 TextEdit 裡所輸入的文字,在上圖可以看到 TextEdit 的內容是"Please input something" ,但在設計介面時看不到這段文字,這是因為範例在城市開啟時修改了 TextEdit 的內容,這段程式是可以在 MainWindow::MainWindow()裡找到,內容如下
ui->textEdit->setText(tr("Pleas input something") );

TextEdit 的內容用 setText() 來修改,但中間多了個 tr() ,這是因為 Qt 的字串型別為 QString ,而常用的 char* 無法自動轉成 QString ,所以透過 tr() 來轉型。

  TextEdit 的內容又是如何提取的呢?可以在 MainWindow::onPushButtonClicked() 裡找到,內容如下
qDebug("TextEdit:%s",ui->textEdit->toPlainText().toLocal8Bit().data() );

qDebug() 在 Qt 的拖拉 widget 與事件 時就用過了,就不再介紹了,內容的部分可以看到是透過 toPlainText() 來取得型別為 QString 的內容,但 QDebug() 需要的型別為 char* ,所以還要再轉型,透過 toLocal8Bit() 轉型為 QByteArray 後,透過 QByteArray::data() 來提取 char* ,這個過程有些冗長,但我查了一下並沒找到更好的轉型。

  如果要透過設計介面來輸入 TextEdit 的顯示內容的話,可以在 TextEdit 雙擊滑鼠,會跳出編輯介面,如下圖
在設計介面輸入 TextEdit 的預設文字

如圖,在欲編輯的 TextEdit 雙擊滑鼠,就會看到編輯介面,編輯介面可以到可以調整文字的對齊與粗體,甚至可以插圖片!這是由於 TextEdit 是用 HTML 的方式來儲存內容,而這次的範例只使用文字的部分而已,以後有機會在介紹更多的用法。

參考資料

[ doc.qt.io ] QString Class

相關文章

Qt 的拖拉 widget 與事件
[ GitLab ] HelloQt

2020年5月18日 星期一

Qt 的拖拉 widget 與事件

Qt 的拖拉 widget 與事件

前言

  在之前的 Qt Creator 入門 裡建置了基本的專案,這次會拖拉 widget 並增加事件,在此做個紀錄。

內容

  由於 Qt 的每個 widget 有各自的用法,所以我在  [ GitLab ] HelloQt 放了個專案來儲存這些用法的範例,這次會使用到 (HelloQt' directory)/PushButton/Basic 裡的專案來解說,用 Qt Creator 來開啟該資料夾的專案檔(HelloQt.pro),如下圖
開啟專案

接著會看到選擇組態的畫面,如下圖
選擇組態

這裡選擇需要的組態,組態會引響使用的編譯器與作業系統的位元數,圖中所選的編譯器是 MSVC 位元數為 64 位元,選擇完後按下右下角的"Configure project",專案的組態就完成了。

  在專案的組態完成後,在 UI 的檔案雙擊滑鼠到設計介面,如下圖
雙擊 UI 的檔案到設計介面

設計介面如下圖
設計介面

區塊1裡會有 Qt 提供的 Widget 的工具箱,用滑鼠拖曳到區塊2就可以新增 widget ,整個 UI 會被記錄成一個樹狀的結構,這個結構會顯示在區塊3,而區塊4會顯示目前所選的 widget 的屬性。這次我使用 PushButton 這個 widget ,其實就是很常見的按鈕,點選區塊2裡已經拖好的 widget 看它的屬性,如下圖
按鈕的屬性

按鈕的屬性裡有一個"objectName",這個是 widget 的名稱,所有的 widget 的名稱必須是唯一的,用 C++ 控制 widget 時會用這個名稱作為變數的名稱,待會會說明,而 "text"可以調整按鈕上所顯示的文字。

  接著先同步專案,如果有更動到 widget 的名稱,不論是新增、修改或移除時請先同步一次專案,如何同步呢?如下圖
同步專案

先清除專案後,再執行 qmake ,這樣就完成同步專案。

  接著來為按鈕增加事件,回到專案的 mainwindow.cpp 檔裡實驗一下專案是否同步

確認專案是否同步

在 MainWindow::MainWindow() 裡輸入"ui->"後,看 IDE跳出來的變數裡有沒有按鈕的名稱( pushButton ),如果沒有表示專案沒同步,請做一次同步的動作。

  接著來綁定按鈕的事件,我們需要先做一個當按鈕被按下後會啟動的 function ,可以在 mainwindow.h 裡找到它,如下
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
  Q_OBJECT

public:
  MainWindow(QWidget *parent = nullptr);
  ~MainWindow();
private slots:
  void onPushButton_Clicked(bool checked);
private:
  Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H

紅色的部分是新增的部分,要注意有個 C++ 沒有的"slots",實作的內容如下
void MainWindow::onPushButton_Clicked(bool checked)
{
  qDebug("Hello Qt");
}

qDebug() 是 Qt 裡提供顯示 debug 訊息的 function ,用法類似 printf() ,接著綁定事件的部分在
 MainWindow::MainWindow() 裡,如下
connect(ui->pushButton,&QPushButton::clicked,this,&MainWindow::onPushButton_Clicked);

參數1就是按鈕的變數,參數2是按鈕的事件,參數3是當事件發生後要被通知的對象,範例的對象就是 MainWindow 自己,參數4 則是要被喚起的 funciton ,綁訂完後執行,按下"HelloQt"按鈕,如下圖
按下按鈕後顯示訊息

在應用程式輸出的分頁裡可以看到訊息。如果要解除事件綁定可以用以下
disconnect(ui->pushButton,&QPushButton::clicked,this,&MainWindow::onPushButton_Clicked);

參數的形式和 connect() 一樣,範例中在 MainWindow::~MainWindow() 解除綁定,但其實這個動作是沒有必要的, Qt 在 widget 被刪除時會自動解除綁定,此處只是做個解除的示範而已。

相關文章

Qt Creator 入門
[ GitLab ] HelloQt

2020年5月11日 星期一

Qt 的專案檔

Qt 的專案檔

前言

  在之前的 Qt 的拖拉 widget 與事件 中介紹了基本的應用,但專案檔並沒有介紹到,在此把學習的過程做個紀錄。

內容

  Qt 的專案檔附檔名為"pro",就拿上次在 Qt 的拖拉 widget 與事件 裡所使用的專案來介紹,在 Qt Creator 打開它會看到以下
QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++11

# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
    main.cpp \
    mainwindow.cpp

HEADERS += \
    mainwindow.h

FORMS += \
    mainwindow.ui

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

內容其實就是個類似 Linux 的 makefile ,但並不一樣,所以 Qt 稱為 qmake 。這裡將常用的變數做個介紹
DEFINES:
這個變數是增加前置處理的定義用的,可以自己增加,範例如下
DEFINES += MY_DEFINE1
DEFINES += MY_DEFINE2

SOURCES:
這裡新增的是要編譯的 .cpp 或 .c 檔,要新增多個檔案的話可以用"\"來區隔,而且支援相對路徑,範例如下
SOURCES += \
    main.cpp \
    ../myLib.cpp

HEADERS:
這個變數類似 SOURCES ,但新增的是 .h 檔,一樣用"\"來區隔來新增多個檔案,一樣支援相對路徑。

FORMS:
這個新增的是 UI 的設計檔。

INCLUDEPATH:
這個變數可以新增 include 的路徑,支援相對路徑,範例如下
INCLUDEPATH += ../include
INCLUDEPATH += ../../myLib

LIBS:
這個變數用來新增 .lib 檔,用法有點特別,因為要連命令參數一起輸入,而且可以新增路徑,範例如下
LIBS += -L../lib -lTestLib

"-L"後直接輸入要新增的路徑,無須空白,"-l"後也不須空白,且不加附檔名。

執行階段程式庫:
QMAKE_CFLAGS_DEBUG += /MTd
QMAKE_CXXFLAGS_DEBUG += /MTd

後面的參數有 4 種,MDd(Multi-threaded DLL Debug) 、 MTd(Multi-threaded Debug) 、 MD(Multi-threaded DLL) 與 MT(Multi-threaded),修改完後須重建才能生效。
 
  接著介紹一下實用的內建 function ,
message():
這個是拿來列印訊息用的,具體的用法如下
message("Hello qmake")
message( $${SOURCES} )

第一個範例會直接列印"Hello qmake",第二個範例是列印變數的內容,列印"SOURCES"這個變數的內容, 這個要注意的是格式為 $${ (變數名稱) } 。

CONFIG():
這個 function 用來對 Debug 與 Release 版做出差異,並注意 function 名稱為大寫,範例如下
CONFIG( debug , debug|release){
  DEFINES += BUILD_DEBUG
}
CONFIG( release , debug|release){
  DEFINES += BUILD_RELEASE
}

contains():
這個 function 用來檢查變數內是否含有某些內容,最基本的用法是用來判斷不同平台建置時給予不同的行為,範例如下
//Build for Windows
contains( QMAKE_HOST.os , Windows ){
  DEFINES += BUILD_WINDOWS
}
//Build for Linux
contains( QMAKE_HOST.os , Linux ){
  DEFINES += BUILD_LINUX
}
//Build for 64 bit
contains( QT_ARCH , x86_64 ){
  DEFINES += BUILD_OS64
}

function 的第一個變數是被尋找的變數,第二個則是要尋找的內容,要注意都有大小寫得分別,Qt 的預設變數可以在 [ Qt ] Variables 裡查詢。

  自訂變數的用法如下
MY_VAR = test
message( $${MY_VAR} )

變數的定義與 makefile 一樣,但如果要指名內容時要注意 qmake 特有的格式。

  本篇記錄了目前用的到的變數與 function ,如果有新的變數也就直接加在這篇,方便日後查詢。

參考資料

[ Qt ] Variables
[ Qt ] Test Functions

相關文章

Qt 的拖拉 widget 與事件

2020年5月4日 星期一

Qt Creator 入門

Qt Creator 入門

前言

  在上一篇 在 Ubuntu 上安裝 Qt 裡有稍微提到 Qt Creator ,它是一個 Qt 自帶的 IDE ,本來打算用 Visial studio 來使用 Qt ,但發現這樣不能跨平台,所以還是決定來學習 Qt Creator ,在此把學習的過程過個紀錄。

內容

  以下範例已將介面風格改為"Dark",可以參照 在 Ubuntu 上安裝 Qt 來修改。開啟 Qt Creator 後,創建新的專案,如下圖
創建新的專案

接著會到下圖
使用範本創建專案

選取"Qt Widgets Application"後,按下"Choose"按鍵,接著來到下圖
決定專案的名稱

這裡會決定專案的名稱與專案創建的位址,決定後"下一步"
選擇建置系統


這裡選擇預設的"qmake"後就下一步
設定預設的視窗類別名稱

這裡會設定視窗的類別名稱,照預設值直接"下一步"
設定語言

這裡設定語言,照預設值直接"下一步"
選擇需要的組態

這裡要選擇需要的組態,預設會全選,這裡我只選擇"MSVC2017 64bit",接著"下一步"
檢視創建專案的狀況

最後檢視專案創建的狀況後按下"完成",完成後看到下圖
完成後的專案

按下"F5"來 Run ,可以看到下圖
執行結果

執行的結果就是個空視窗,如果要選擇 Debug 或 Release 版的建置的話,可以在 IDE 的左下做選擇
建置組態的選擇

  這次介紹了如何創建專案,但創建好的專案只有一個空視窗,下次會介紹如何增加 Widget 與事件的綁定。

相關文章

在 Ubuntu 上安裝 Qt
Qt 入門