#頭條創作挑戰賽#
1. QWidget
QWidget類是所有視窗類的父類(控件類是也屬于視窗類), 并且QWidget類的父類的QObject, 也就意味着所有的視窗類對象隻要指定了父對象, 都可以實作記憶體資源的自動回收。這裡給大家介紹一下關于這個類常用的一些API函數。
// 構造函數
QWidget::QWidget(QWidget *parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags());
// 公共成員函數
// 給目前視窗設定父對象
void QWidget::setParent(QWidget *parent);
void QWidget::setParent(QWidget *parent, Qt::WindowFlags f);
// 擷取目前視窗的父對象, 沒有父對象傳回 nullptr
QWidget *QWidget::parentWidget() const;
//------------- 視窗位置 -------------
// 得到相對于目前視窗父視窗的幾何資訊, 邊框也被計算在内
QRect QWidget::frameGeometry() const;
// 得到相對于目前視窗父視窗的幾何資訊, 不包括邊框
const QRect& geometry() const;
// 設定目前視窗的幾何資訊(位置和尺寸資訊), 不包括邊框
void setGeometry(int x, int y, int w, int h);
void setGeometry(const QRect &);
//此屬性儲存小部件的内部幾何形狀,不包括任何視窗架構,等于QRect(0,0, width(), height())
QRect rect();
//擷取小控件在父控件中的位置
QPoint pos() const
// 移動視窗, 重新設定視窗的位置
void move(int x, int y);
void move(const QPoint &);
//------------- 視窗尺寸 -------------
// 擷取目前視窗的尺寸資訊
QSize size() const
// 重新設定視窗的尺寸資訊
void resize(int w, int h);
void resize(const QSize &);
// 擷取目前視窗的最大尺寸資訊
QSize maximumSize() const;
// 擷取目前視窗的最小尺寸資訊
QSize minimumSize() const;
// 設定目前視窗固定的尺寸資訊
void QWidget::setFixedSize(const QSize &s);
void QWidget::setFixedSize(int w, int h);
// 設定目前視窗的最大尺寸資訊
void setMaximumSize(const QSize &);
void setMaximumSize(int maxw, int maxh);
// 設定目前視窗的最小尺寸資訊
void setMinimumSize(const QSize &);
void setMinimumSize(int minw, int minh);
// 擷取目前視窗的高度
int height() const;
// 擷取目前視窗的最小高度
int minimumHeight() const;
// 擷取目前視窗的最大高度
int maximumHeight() const;
// 給視窗設定固定的高度
void QWidget::setFixedHeight(int h);
// 給視窗設定最大高度
void setMaximumHeight(int maxh);
// 給視窗設定最小高度
void setMinimumHeight(int minh);
// 擷取目前視窗的寬度
int width() const;
// 擷取目前視窗的最小寬度
int minimumWidth() const;
// 擷取目前視窗的最大寬度
int maximumWidth() const;
// 給視窗設定固定寬度
void QWidget::setFixedWidth(int w);
// 給視窗設定最大寬度
void setMaximumWidth(int maxw);
// 給視窗設定最小寬度
void setMinimumWidth(int minw);
//------------- 視窗圖示 -------------
// 得到目前視窗的圖示
QIcon windowIcon() const;
// 構造圖示對象, 參數為圖檔的路徑
QIcon::QIcon(const QString &fileName);
// 設定目前視窗的圖示
void setWindowIcon(const QIcon &icon);
/*--Slots--*/
//------------- 視窗标題 -------------
// 得到目前視窗的标題
QString windowTitle() const;
// 設定目前視窗的标題
void setWindowTitle(const QString &);
void setWindowModified(bool)
// 判斷視窗是否可用
bool isEnabled() const;
// 設定視窗是否可用, 不可用視窗無法接收和處理視窗事件
void setEnabled(bool);
//------------- 視窗顯示 -------------
// 關閉目前視窗
[slot] bool QWidget::close();
// 隐藏目前視窗
[slot] void QWidget::hide();
// 顯示目前建立以及其子視窗
[slot] void QWidget::show();
//設定視窗是否可見
virtual void setVisible(bool visible)
// 全屏顯示目前視窗, 隻對windows有效
[slot] void QWidget::showFullScreen();
// 視窗最大化顯示, 隻對windows有效
[slot] void QWidget::showMaximized();
// 視窗最小化顯示, 隻對windows有效
[slot] void QWidget::showMinimized();
// 将視窗回複為最大化/最小化之前的狀态, 隻對windows有效
[slot] void QWidget::showNormal();
//------------- 信号 -------------
// QWidget::setContextMenuPolicy(Qt::ContextMenuPolicy policy);
// 視窗的右鍵菜單政策 contextMenuPolicy() 參數設定為 Qt::CustomContextMenu, 按下滑鼠右鍵發射該信号
[signal] void QWidget::customContextMenuRequested(const QPoint &pos);
// 視窗圖示發生變化, 發射此信号
[signal] void QWidget::windowIconChanged(const QIcon &icon);
// 視窗标題發生變化, 發射此信号
[signal] void QWidget::windowTitleChanged(const QString &title);
【領更多QT學習資料,點選下方連結免費領取↓↓,先碼住不迷路~】
點選→領取Qt開發進階技術棧學習路線和資料
設定滑鼠樣式
Qcursor
//擷取滑鼠的全局坐标
[static] QPoint pos()
[static] QPoint pos(const QScreen *screen)
//将滑鼠移動到全局的指定坐标
[static] void setPos(int x, int y)
[static] void setPos(QScreen *screen, int x, int y)
[static] void setPos(const QPoint &p)
[static] void setPos(QScreen *screen, const QPoint &p)
//QScreen在多螢幕的時候可用
- 以下代碼可以通過點選按鈕切換并檢視所有滑鼠的(内置)形狀
QPushButton*btn = new QPushButton("切換滑鼠形狀",this);
connect(btn,&QPushButton::clicked,this,[=]()
{
static int i = 0;
this->setCursor(Qt::CursorShape(i));
qDebug()<<"切換成功"<<Qt::CursorShape(i);
i = (i+1)%25;
});
}
除了内置形狀之外,還可以自定義滑鼠形狀
QPixmap* cursorPixmaps[2]={new QPixmap("://images/cursor_one.png"),
new QPixmap("://images/cursor_two.png")};
QPushButton*btn = new QPushButton("切換滑鼠樣式",this);
connect(btn,&QPushButton::clicked,this,[=]()
{
static int i = 0;
setCursor(QCursor(*cursorPixmaps[i]));
i = (i+1)%2;
});
setWhatsThis
setToolTip用來設定提示資訊,那麼setWhatsThis是用來幹嘛的呢?顧名思義就是用來說明這是啥玩意的
- 先建立三個按鈕
QPushButton*btn1 = new QPushButton("open",this);
QPushButton*btn2 = new QPushButton("new",this);
QPushButton*btn3 = new QPushButton("look",this);
btn2->move(100,0);
btn3->move(200,0);
btn1->setToolTip("打開檔案");
btn1->setWhatsThis("open a new file");
btn2->setToolTip("建立檔案");
btn2->setWhatsThis("create a new file");
btn3->setToolTip("檢視");
btn3->setWhatsThis("檢視其他按鈕的詳細資訊");
connect(btn3,&QPushButton::clicked,this,[=]()
{
QWhatsThis::enterWhatsThisMode();
});
運作程式後按Shift + F1會出現目前獲得焦點的widget的whatsThis資訊。
調用QWhatsThis的靜态函數enterWhatsThisMode進入whatsThis模式,此時當滑鼠移動到設定了whatsThis的widget上光标會出現一個問号,再點選則會出現whatsThis的視窗。
設定視窗圖示
- 修改視窗和工作列顯示的圖示
this->setWindowIcon(QIcon("://images/snowBall.png"));
設定應用程式圖示
簡單三步,搞定~
- 1,建立一個圖示格式(ico)的檔案,可以将一個普通的圖檔轉成.ico格式的圖示檔案
- 2,将轉換好的ico檔案放到源檔案所在目錄,即和.pro檔案同級目錄
- 3,在.pro項目檔案中添加如下代碼zay.ico 即圖示名
RC_ICONS += zay.ico
QWidget槽函數
show,hide,setVisible,setHidden,close 小結
- 0,在Qt中如果一定要自己釋放對象,官方推薦使用[slot] void QObject::deleteLater()來釋放對象
- 1,[slot] void setVisible(bool visible) 設定Widget可見或不可見
- 2,slot] void QWidget::setHidden(bool *hidden*) 1号的馬甲
- 3,[slot] void QWidget::show() 1号的馬甲
- 4,[slot] void QWidget::hide() 1号的馬甲
- 5,[slot] bool QWidget::close() 看情況調用4号或者0号(該部件是否有父部件)
呵呵,show()、hide()、setVisible()、setHidden() 這4個函數讓人看得眼花缭亂。怎麼辦?
看看代碼吧:
virtual void setVisible(bool visible);
inline void setHidden(bool hidden) { setVisible(!hidden); }
inline void show() { setVisible(true); }
inline void hide() { setVisible(false); }
代碼很清楚:這四個東西之中,隻有 setVisible 是獨立的,其他三個都是它的馬甲! setVisible 的作用是什麼呢?顧名思義,使得一個Widget可見或不可見。 要點:不可見,是Widget不在界面上顯示,但不代表對象被析構!
//[1]建立關閉自己的按鈕
QPushButton* closeBtn = new QPushButton("closeSelf",this);
connect(closeBtn,&QPushButton::clicked,this,&Widget::close);
//點選右上角關閉按鈕會銷毀視窗
connect(this,&QObject::destroyed,this,[](){qDebug()<<"this destroyed";});
//[2]建立子視窗
QWidget* subWidget = new QWidget;
subWidget->setWindowTitle("subWidget");
subWidget->show();
//subWidget->setAttribute(Qt::WidgetAttribute::WA_DeleteOnClose); //點選關閉按鈕時銷毀視窗
connect(subWidget,&QWidget::destroyed,this,[=](){qDebug()<<"subWidget destroyed";});
//[3]建立關閉子視窗的按鈕
QPushButton*closeSubWidgetBtn = new QPushButton("closeSubWidget",this);
closeSubWidgetBtn->move(100,0);
connect(closeSubWidgetBtn,&QPushButton::clicked,subWidget,[=](){
subWidget->close();
subWidget->deleteLater(); //推薦這樣銷毀對象
qDebug()<<subWidget;
});
//[4]建立顯示子視窗的按鈕
QPushButton*showSubWidgetBtn = new QPushButton("showSubWidget",this);
showSubWidgetBtn->move(200,0);
connect(showSubWidgetBtn,&QPushButton::clicked,subWidget,&QWidget::show);
坐标轉換
QPoint mapFrom(const QWidget *parent, const QPoint &pos) const
QPoint mapFromGlobal(const QPoint &pos) const
QPoint mapFromParent(const QPoint &pos) const
QPoint mapTo(const QWidget *parent, const QPoint &pos) const
QPoint mapToGlobal(const QPoint &pos) const
QPoint mapToParent(const QPoint &pos) const
- 這幾個函數都是轉換相對坐标系用的. 用另一個坐标系統的坐标值, 來表達目前坐标系統中某個坐标所指向的某個點,
- 記住: 一定要先确兩個坐标系統再确定一個點
- 相對坐标:擷取自己相對于父控件的位置 QWidget::pos()
- 絕對坐标:将目前控件的相對位置轉換為螢幕絕對位置 QWidget::mapToGlobal()
- 絕對坐标轉為相對坐标:将絕對位置對應到控件的相對位置 QWidget::mapFromGlobal()
設定視窗标志
- 用Qt寫一個視窗,如果繼承QDialog,那視窗就隻有關閉按鈕,如果繼承QWidget,那麼就有關閉,最大化,最小化三個按鈕,怎樣才能讓關閉按鈕可用,而最大化和最小化按鈕不可用呢?
//僅僅顯示關閉按鈕,添加一個幫助按鈕?
this->setWindowFlags(Qt::WindowType::WindowCloseButtonHint | Qt::WindowContextHelpButtonHint);
//從視窗标志中移除幫助按鈕标志
this->setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
//移除标志或單純添加一個标志,可以用一下簡單的函數 true為設定,false為移除
this->setWindowFlag(Qt::WindowContextHelpButtonHint,false);
- 更多标志詳見附錄一
【領更多QT學習資料,點選下方連結免費領取↓↓,先碼住不迷路~】
點選→領取Qt開發進階技術棧學習路線和資料
設定視窗狀态
- 将視窗狀态設定為windowState。 視窗狀态是附錄二中狀态的組合。
- 如果視窗不可見(即isVisible()傳回false),視窗狀态将在調用show()時生效。 對于可見視窗,更改是立即的。 例如,要在全屏模式和普通模式之間切換,請使用以下代碼:
w->setWindowState(w->windowState() ^ Qt::WindowFullScreen);
- 為了恢複和激活最小化的視窗(同時保持其最大化和/或全屏狀态),使用以下方法:
w->setWindowState((w->windowState() & ~Qt::WindowMinimized) | Qt::WindowActive);
- 調用這個函數将隐藏小部件。 必須調用show()使小部件再次可見,在某些視窗系統中,Qt::WindowActive不是立即的,在某些情況下可能會被忽略。
設定屬性
- setAttribute用來設定小部件的屬性,testAttribute檢視是否設定了某種屬性。
常用屬性
枚舉 | 值(十進制) | 描述 |
Qt::WA_AcceptDrops | 78 | 允許來自拖放操作的資料被拖放到小部件上(參見QWidget::setAcceptDrops()) |
Qt::WA_AlwaysShowToolTips | 84 | 為非活動視窗啟用工具提示 |
Qt::WA_CustomWhatsThis | 47 | 表示小部件希望在“這是什麼?”模式下繼續正常運作。 這是由小部件的作者設定的。 |
Qt::WA_DeleteOnClose | 55 | 使Qt在小部件接受關閉事件時删除該小部件 |
Qt::WA_MouseTracking | 2 | 訓示小部件啟用了滑鼠跟蹤。 參見QWidget:: mouseTracking |
Qt::WA_TranslucentBackground | 120 | 訓示小部件應該有一個半透明的背景,也就是說,小部件的任何非透明區域都将是半透明的,因為小部件将有一個alpha通道。 設定此标志将導緻設定WA_NoSystemBackground。 在Windows上,小部件還需要設定Qt:: framesswindowhint視窗标志。 該标志由小部件的作者設定或清除。 |
釋出程式
Qt 官方開發環境使用的動态連結庫方式,在釋出生成的exe程式時,需要複制一大堆 dll,如果自己去複制dll,很可能丢三落四,導緻exe在别的電腦裡無法正常運作。是以 Qt 官方開發環境裡自帶了一個工具:windeployqt.exe(這個檔案在Qt安裝目錄的bin檔案下可以找到)
不同的編譯器和版本需要使用不同的windeployqt版本打包
以官方 Qt 5.14.2+MinGW32 開發環境為例:
- 1,通過Qt指令行運作windeployqt工具,開始菜單->Qt 5.14.2->5.4->MinGW 4.9 (32-bit)->Qt 5.14.2 (MinGW 7.3.0 32-bit)
- 把需要打包的Qt可執行程式拷貝到一個單獨的檔案夾裡面,然後再把指令行工作目錄切換到該檔案夾
- 最後執行指令windeployqt maye.exe
2. 資源檔案 .qrc
需要我們給視窗設定圖示
// 建立圖示對象
QIcon::QIcon(const QString &fileName)
// QWidget類的 公共成員函數
void setWindowIcon(const QIcon &icon)
// 給視窗設定圖示
// 弊端: 釋出的exe 必須要加載 d:\\pic\\1.ico 如果對應的目錄中麼有圖檔, 圖示就無法被加載
// 釋出exe 需要額外釋出圖檔, 将其部署到某個目錄中
setWindowIcon(QIcon("d:\\pic\\1.ico"));
使用資源檔案解決上述的弊端:
優勢:
将圖檔資源放到資源檔案
當程式編譯的時候, 資源檔案中的圖檔會被轉換為二進制, 打包到exe中
直接釋出exe就可以, 不需要額外提供圖檔資源了
資源檔案的建立
- 資源檔案的使用
- 打開資源檔案
- 添加字首
- 添加檔案
- 彈出以檔案選擇對話框, 選擇資源檔案
- 資源檔案放到什麼地方?
- 放到和 項目檔案 .pro 同一級目錄或者更深的目錄中
- 錯誤的做法: 将資源檔案放到 .pro檔案的上級目錄, 這樣資源檔案無法被加載到
- 資源檔案中添加的圖檔資源
- 如何在程式中使用資源檔案中的圖檔
附錄一
- 此枚舉類型用于為小部件指定各種視窗系統屬性。 它們相當不尋常,但在少數情況下是必要的。 其中一些标志取決于底層視窗管理器是否支援它們。
枚舉 | 值(十六進制) | 描述 |
Qt::Widget | 0x00000000 | 這是QWidget的預設類型。 這種類型的小部件如果有父部件,則為子部件,如果沒有父部件,則為獨立視窗。 |
Qt::Window | 0x00000001 | 訓示小部件是一個視窗,通常帶有視窗系統架構和标題欄,而不管小部件是否有父視窗。 |
Qt::Dialog | 0x00000002| Window | 訓示小部件是一個視窗,應該裝飾為一個對話框(即,通常在标題欄中沒有最大化或最小化按鈕)。 |
Qt::Sheet | 0x00000004| Window | 訓示視窗是macOS上的工作表。 由于使用工作表意味着視窗模式,推薦的方法是使用QWidget::setWindowModality(),或QDialog::open() |
Qt::Drawer | Sheet | Dialog | 訓示小部件是macOS上的一個抽屜 |
Qt::Popup | 0x00000008| Window | 訓示小部件是彈出式頂級視窗,即它是模态視窗,但具有适合于彈出式菜單的視窗系統架構。 |
Qt::Tool | Popup | Dialog | 訓示小部件是工具視窗。 工具視窗通常是一個小視窗,比通常的标題欄和裝飾更小,通常用于工具按鈕集合 |
Qt::ToolTip | Popup | Sheet | 訓示小部件是一個工具提示。 這在内部用于實作工具提示 |
Qt::SplashScreen | ToolTip | Dialog | 表示該視窗為啟動畫面。 這是QSplashScreen的預設類型 |
Qt::Desktop | 0x00000010| Window | 訓示此小部件是桌面。 這是QDesktopWidget(此類已經過時)的類型 |
Qt::SubWindow | 0x00000012 | 訓示此小部件是子視窗,例如QMdiSubWindow小部件 |
Qt::ForeignWindow | 0x00000020| Window | 表示此視窗對象是一個句柄,表示由另一個程序或手動使用本機代碼建立的本機平台視窗。 |
Qt::CoverWindow | 0x00000040| Window | 訓示該視窗表示覆寫視窗,該視窗在某些平台上最小化應用程式時顯示。 |
- 視窗提示可以有多個(不一定會生效,看平台是否支援)
枚舉 | 值(十六進制) | 描述 |
Qt::FramelessWindowHint | 0x00000800 | 産生一個無邊框的視窗。 使用者不能通過視窗系統移動或調整無邊框視窗的大小 |
Qt::NoDropShadowWindowHint | 0x40000000 | 去掉視窗陰影 |
Qt::CustomizeWindowHint | 0x02000000 | 關閉預設的視窗标題提示 |
Qt::WindowTitleHint | 0x00001000 | 給視窗一個标題欄 |
Qt::WindowSystemMenuHint | 0x00002000 | 添加一個視窗系統菜單,可能還有一個關閉按鈕(例如在Mac上)。 如果你需要隐藏或顯示關閉按鈕,使用WindowCloseButtonHint更便于移植。 |
Qt::WindowMinimizeButtonHint | 0x00004000 | 添加一個最小化按鈕 |
Qt::WindowMaximizeButtonHint | 0x00008000 | 添加一個最大化按鈕 |
Qt::WindowMinMaxButtonsHint | WindowMinimizeButtonHint |WindowMaximizeButtonHint | 添加最小化和最大化按鈕 |
Qt::WindowCloseButtonHint | 0x08000000 | 添加一個關閉按鈕 |
Qt::WindowContextHelpButtonHint | 0x00010000 | 向對話框添加上下文幫助按鈕 |
Qt::WindowStaysOnTopHint | 0x00040000 | 通知視窗系統該視窗應該位于所有其他視窗的頂部 |
Qt::WindowStaysOnBottomHint | 0x04000000 | 通知視窗系統該視窗應位于所有其他視窗的底部 |
附錄二
- 視窗狀态 Qt::WindowState
枚舉 | 值 | 描述 |
Qt::WindowNoState | 0x00000000 | 視窗沒有狀态設定(正常狀态) |
Qt::WindowMinimized | 0x00000001 | 視窗被最小化(即圖示化) |
Qt::WindowMaximized | 0x00000002 | 窗戶周圍有一個架構,使其最大化 |
Qt::WindowFullScreen | 0x00000004 | 視窗填充了整個螢幕,周圍沒有任何邊框 |
Qt::WindowActive | 0x00000008 | 該視窗是活動視窗,即它有鍵盤焦點 |