国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【Qt設(shè)計(jì)開(kāi)發(fā)】GUI界面設(shè)計(jì)開(kāi)發(fā)

這篇具有很好參考價(jià)值的文章主要介紹了【Qt設(shè)計(jì)開(kāi)發(fā)】GUI界面設(shè)計(jì)開(kāi)發(fā)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。


??本文是我在學(xué)習(xí)QT的GUI界面設(shè)計(jì)過(guò)程當(dāng)中的心得和學(xué)習(xí)筆記,在學(xué)習(xí)時(shí)已經(jīng)有C, C++,Python的基礎(chǔ)。文章附上了學(xué)習(xí)的代碼,僅供大家參考。如果有問(wèn)題,有錯(cuò)誤歡迎大家留言。此外,博主還有另外幾篇文章,分別關(guān)于 Python基礎(chǔ)知識(shí)、 Python的具體應(yīng)用、 C語(yǔ)言指針結(jié)構(gòu)體的難點(diǎn)、 C++入門和進(jìn)階知識(shí)點(diǎn)C++高階知識(shí)點(diǎn),大家點(diǎn)擊即可翻閱。

一、Qt簡(jiǎn)介和下載安裝

??Qt是一個(gè)1991年由Qt Company開(kāi)發(fā)的跨平臺(tái)C++圖形用戶界面(Graphic User Interface, GUI)應(yīng)用程序開(kāi)發(fā)框架。QT包括但不僅限于GUI的開(kāi)發(fā),也包含了諸如系統(tǒng)調(diào)用、網(wǎng)絡(luò)編程、數(shù)據(jù)庫(kù)編程,2D/3D圖形處理等等。QT具有強(qiáng)大的跨平臺(tái)運(yùn)行的性能,幾乎囊括了所有的操作系統(tǒng),例如Linux、Windows、Mac OS、Android、IOS。我們所熟知的金山WPS、Google Earth谷歌地圖、SKype網(wǎng)絡(luò)電話就是用Qt開(kāi)發(fā)的。

??博主使用的版本是Qt 5.14.2, 下載、安裝 參照B站視頻。

二、Qt入門

2.1 創(chuàng)建第一個(gè)項(xiàng)目

??第一步,選擇new->Application->Qt Widgets Application->Choose:

qt界面開(kāi)發(fā),C++,qt

??第二步,修改項(xiàng)目名稱和項(xiàng)目路徑,點(diǎn)擊下一步。

qt界面開(kāi)發(fā),C++,qt

??第三步,修改類名稱,其中基類有三種,分別是QMainWindow(菜單類), QWidget, QDialog(對(duì)話框類),表示創(chuàng)建的類繼承的基類,例如,圖中所示mywidget類的父類就是QWidget。QDialog和QMainWindow是QWidget的子類。QMainWindow是菜單類,左上角有一些菜單選項(xiàng),右上角有最小化最大化按鈕。QDialog是對(duì)話框類,下圖所示就是一個(gè)對(duì)話框類。

qt界面開(kāi)發(fā),C++,qt

??第四步,選擇MinGW 64-bit 編譯器,32位和64位的區(qū)別在于32位能在64位的機(jī)器上跑,64位不能在32位的機(jī)器上跑,初始項(xiàng)目選擇任意一個(gè)就可以,點(diǎn)擊下一步,然后在點(diǎn)擊完成,就可以產(chǎn)生一個(gè)名為Qt_test的項(xiàng)目,項(xiàng)目底下有一個(gè)Qt_test.pro的項(xiàng)目文件。
qt界面開(kāi)發(fā),C++,qt

??之后的步驟默認(rèn)就可以,一直點(diǎn)下一步,然后編譯運(yùn)行,出現(xiàn)一個(gè)空白窗口,創(chuàng)建完畢。

qt界面開(kāi)發(fā),C++,qt

??編譯成功后,會(huì)在項(xiàng)目目錄底下生成build文件,然后點(diǎn)擊debug文件,里面有生成的.exe可執(zhí)行文件,點(diǎn)擊即可運(yùn)行,結(jié)果就是一個(gè)空白圖窗。博主在運(yùn)行.exe的時(shí)候碰到了錯(cuò)誤彈窗,顯示程序“無(wú)法找到入口”,添加了環(huán)境變量之后還需要將環(huán)境變量上移,具體解決參考解決Qt生成exe錯(cuò)誤:無(wú)法定位程序輸入點(diǎn)。

# QT_hello.pro文件
QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
    # 版本大于4以上的添加widgets模塊

CONFIG += c++11 # 用C++11標(biāo)準(zhǔn)來(lái)解釋代碼

# 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 \
    mywidget.cpp

HEADERS += \
    mywidget.h

TARGET = UAV    # 生成的.exe文件名稱
TEMPLATE = app  # 應(yīng)用程序模板 Application
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
// mywidget.h文件
#ifndef MYWIDGET_H
#define MYWIDGET_H
#include <QWidget>
class mywidget : public QWidget // 公共繼承
{
    Q_OBJECT    // Q_OBJECT宏,允許類中使用信號(hào)和槽的機(jī)制

public:
    mywidget(QWidget *parent = nullptr);    // 構(gòu)造函數(shù)
    ~mywidget();    // 析構(gòu)函數(shù)
};
#endif // MYWIDGET_H
// main.cpp文件
# include <QApplication>
# include <QtWidgets>
# include <QDebug>
// main程序入口     argc命令行變量數(shù)量, argv命令行變量的數(shù)組
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);    // 應(yīng)用程序?qū)ο螅?在QT中,應(yīng)用程序?qū)ο笥星覂H有一個(gè)    
    mywidget w;  // 窗口對(duì)象 mywidget是Qwidget的子類
    w.show();	// show方法, 窗口對(duì)象默認(rèn)不會(huì)顯示
	qDebug()<<"hello world";    // 在控制臺(tái)輸出, 用于調(diào)試    
    return a.exec();	// 讓應(yīng)用程序?qū)ο筮M(jìn)入消息循環(huán)
}
// mywidget.cpp文件
#include "mywidget.h"
mywidget::mywidget(QWidget *parent)
    : QWidget(parent)
{
}
mywidget::~mywidget()
{
}

2.2 快捷鍵和命名規(guī)范

??QT如下,可以提高編碼效率:

/* 快捷鍵
 * 運(yùn)行代碼: Ctrl + r
 * 編譯:	Ctrl + b
 * 注釋:	Ctrl + /
 * 縮放字體:Ctrl + 滾輪
 * 查找/替換字體: Ctrl + f
 * 整行移動(dòng)代碼: Ctrl + Shift + 上/下鍵
 * 自動(dòng)對(duì)齊:Ctrl + i
 * 在同名文件和源文件之間切換: F4
 * 快速添加函數(shù)定義:鼠標(biāo)移到聲明的那一行,按Alt + Enter
 * 修改變量名,并應(yīng)用到所有:Ctrl + Shift + r
 * 快捷打開(kāi)輸出窗口: Alt + number(1-8)
 * 書簽功能: 快速跳到代碼
 * 			Ctrl + M 添加/刪除標(biāo)簽
 * 			Ctrl + . 查找并移動(dòng)到下一個(gè)標(biāo)簽處
 * 查看幫助文檔:
 * 			第一種:Qt Creator 查看 F1
 * 			第二種:獨(dú)立的幫助文檔程序查看
*/

/*
類名: 首字母大寫,單詞和單詞之間首字母大寫
函數(shù)名和變量名稱: 首字母小寫,單詞和單詞之間首字母大寫
*/

qt界面開(kāi)發(fā),C++,qt

??Qt設(shè)計(jì)師創(chuàng)建的文件后綴為.ui, 無(wú)法直接運(yùn)用到C++中,因此引入一個(gè)uic工具,可以將.ui文件轉(zhuǎn)換為.c文件。rcc moc同樣是這樣類型的工具,將一些qt文件轉(zhuǎn)換成C++語(yǔ)法格式的文件。

2.3 Qt項(xiàng)目和VS2022項(xiàng)目相互轉(zhuǎn)換

??博主最近需要使用QT和VS 2022聯(lián)合編程,大家有需要也可以參考視頻 VS項(xiàng)目和QT項(xiàng)目相互轉(zhuǎn)換。

??使用VS2022創(chuàng)建的QT項(xiàng)目,輸出為.pro文件,利用Qt createor打開(kāi),需要在.pro文件中加載模塊(添加如下代碼),因?yàn)閂S2022是在項(xiàng)目配置的時(shí)候加載的。如下圖所示。

# ----------------------------------------------------
# This file is generated by the Qt Visual Studio Tools.
# ------------------------------------------------------

QT += core gui widgets  
# 模塊加載, 使用VS2022創(chuàng)建的項(xiàng)目,輸出為.pro文件,利用Qt createor打開(kāi),需要在.pro文件中加載模塊
# 因?yàn)閂S2022是在項(xiàng)目配置的時(shí)候加載的。

TEMPLATE = app
TARGET = QtWidgetsTest

##########################################
# 以下代碼可以不要
DESTDIR = ../x64/Debug
CONFIG += debug
LIBS += -L"."
DEPENDPATH += .
MOC_DIR += GeneratedFiles/$(ConfigurationName)
OBJECTS_DIR += debug
UI_DIR += GeneratedFiles
RCC_DIR += GeneratedFiles
###########################################
HEADERS += ./qtwidgetstest.h
SOURCES += ./qtwidgetstest.cpp \
    ./main.cpp
FORMS += ./qtwidgetstest.ui
RESOURCES += qtwidgetstest.qrc

qt界面開(kāi)發(fā),C++,qt

    w.setWindowTitle(u8"VS2022 QT 窗口"); // 不亂碼
    /* 
    產(chǎn)生亂碼, 英文不會(huì)有亂碼,英文編碼格式都是同意的ASCII,QT中文編碼格式是UTF-8,
    windows中文編碼格式是GB2312,u8為轉(zhuǎn)換成UTF-8,QT就可以識(shí)別了  
    */

三、Qt基礎(chǔ)

3.1 Qt對(duì)象樹(shù)和窗口坐標(biāo)系概念

??當(dāng)創(chuàng)建的對(duì)象在堆區(qū)的時(shí)候,如果指定的父親是QObject派生下來(lái)的類或者QObject子類派生下來(lái)的類,可以不用管理釋放操作,QT會(huì)對(duì)象會(huì)放入到對(duì)象樹(shù)中,會(huì)自動(dòng)釋放內(nèi)存,一定程度上簡(jiǎn)化了內(nèi)存回收機(jī)制。這也是QT的優(yōu)點(diǎn)之一,因此,我們?cè)跇?gòu)造時(shí)候就指定parent對(duì)象,就不需要操心內(nèi)存釋放問(wèn)題。

??Qt窗口的坐標(biāo)系:以左上角頂點(diǎn)為原點(diǎn)(0, 0),X向右增加,Y向下增加。對(duì)于嵌套窗口,其坐標(biāo)系是相對(duì)于父窗口而言。

3.2 QPushButton

??在編寫這部分代碼時(shí),博主的編輯器竟然沒(méi)有代碼補(bǔ)全功能,于是又在網(wǎng)上找了解決辦法,這里給出鏈接。
??在學(xué)習(xí)QT的各種類的過(guò)程中,最重要的是 學(xué)會(huì)如何查找?guī)椭臋n以及看懂幫助文檔。例如QPushButton類,幫助文檔中給出詳細(xì)解釋:添加頭文件,同時(shí)要在.pro文件中加入widgets模塊,其父類是QAbstractButton,其子類是QCommandLinkButton等等信息。

qt界面開(kāi)發(fā),C++,qt

3.3 信號(hào)和槽(signals and slots)

3.3.1 pushbutton關(guān)閉窗口

??信號(hào)和槽是學(xué)習(xí)Qt的一個(gè)非常重要知識(shí)點(diǎn),在信號(hào)和槽當(dāng)中,我們引入一個(gè)連接函數(shù)connect( ),將信號(hào)發(fā)送者和信號(hào)接收者鏈接起來(lái)。connect( )一共有四個(gè)參數(shù)

  • 參數(shù)1:信號(hào)發(fā)送者;
  • 參數(shù)2:發(fā)送的信號(hào)(函數(shù)地址);
  • 參數(shù)3:信號(hào)接收者;
  • 參數(shù)4:處理的槽函數(shù)(函數(shù)地址)。

??在空白項(xiàng)目的基礎(chǔ)上改寫mywidget.cpp函數(shù),實(shí)現(xiàn)點(diǎn)擊按鈕,關(guān)閉窗口案例:

# include "mywidget.h"
# include <QPushButton>
# include <QDebug>

mywidget::mywidget(QWidget *parent)
    : QWidget(parent)
{
    qDebug() << "hello world";  // 調(diào)試信息
    // 創(chuàng)建一個(gè)按鈕
    QPushButton * btn = new QPushButton;
    //btn->show();    // show以頂層(新窗口)的方式彈出窗口控件
    btn->setParent(this);   // 讓btn對(duì)象依賴在mywidget窗口中
    btn->setText("第一個(gè)按鈕");
    QPushButton *btn2 = new QPushButton("第二個(gè)按鈕",this);
    btn2->move(100,100);    // 移動(dòng)btn2按鈕
    resize(600,400);    // 重置窗口大小
    btn2->resize(50,50);    // 設(shè)置btn2按鈕大小
    setWindowTitle("第一個(gè)窗口應(yīng)用");  // 設(shè)置窗口名稱
    connect(btn,&QPushButton::clicked, this, &mywidget::close);
}
mywidget::~mywidget()
{
}

3.3.2 自定義信號(hào)和槽

??創(chuàng)建一個(gè)下課,老師餓了,學(xué)生請(qǐng)客的案例。添加自定義的老師類和學(xué)生類,選擇C++類,這個(gè)兩個(gè)類不是窗口類,直接繼承QObject類。分別產(chǎn)生了teacher和student的.cpp .h文件。

qt界面開(kāi)發(fā),C++,qt

??頭文件中定義,變量名稱和函數(shù)聲明,在.cpp文件中寫實(shí)現(xiàn)。

// mywidget.h
#ifndef MYWIDGET_H
#define MYWIDGET_H

#include <QWidget>
# include "teacher.h"
# include "student.h"

class mywidget : public QWidget // 公共繼承
{
    Q_OBJECT    // Q_OBJECT宏,允許類中使用信號(hào)和槽的機(jī)制

public:
    mywidget(QWidget *parent = nullptr);    // 構(gòu)造函數(shù)
    ~mywidget();    // 析構(gòu)函數(shù)

    Teacher *t;     // 在頭文件中聲明變量和函數(shù)
    Student *s;
    void ClassIsOver();
};
#endif // MYWIDGET_H
// student.h
#ifndef STUDENT_H
#define STUDENT_H

#include <QObject>

class Student : public QObject
{
    Q_OBJECT
public:
    explicit Student(QObject *parent = nullptr);

signals:

public slots:
    /* 早期的QT版本必須要寫到,public slots,高級(jí)版本可以寫到public或全局下
     * 返回值void,需要聲明,也需要實(shí)現(xiàn)
     * 可以有參數(shù),可以發(fā)生重載
     */
    void treat();
    void treat(QString foodName);
};

#endif // STUDENT_H
// teacher.h
#ifndef TEACHER_H
#define TEACHER_H

#include <QObject>

class Teacher : public QObject
{
    Q_OBJECT
public:
    explicit Teacher(QObject *parent = nullptr);

signals:
    /* 自定義信號(hào)類,沒(méi)有返回值
     * 只需要聲明,不需要實(shí)現(xiàn)
     * 可以有參數(shù),可以重載
     */
    void hungry();
    void hungry(QString foodName);
public slots:
    /* 早期的QT版本必須要寫到,public slots,高級(jí)版本可以寫到public或全局下
     * 返回值void,需要聲明,也需要實(shí)現(xiàn)
     * 可以有參數(shù),可以發(fā)生重載
     */
};

#endif // TEACHER_H
// mywidget.cpp
# include "mywidget.h"
# include <QPushButton>
# include <QDebug>

mywidget::mywidget(QWidget *parent)
    : QWidget(parent)
{
    // 創(chuàng)建老師和學(xué)生對(duì)象
    this->t = new Teacher(this);
    this->s = new Student(this);
    // 無(wú)參
//    //ClassIsOver();  // 調(diào)用下課函數(shù)   沒(méi)有鏈接,沒(méi)有任何響應(yīng)
//    connect(t,&Teacher::hungry, s, &Student::treat);    // 先鏈接后觸發(fā)信號(hào),才能響應(yīng)
//    ClassIsOver();  // 調(diào)用下課函數(shù)
    // 鏈接代參數(shù)的函數(shù),
    void (Teacher:: *f1)(QString) = &Teacher::hungry;
    void (Student:: *f2)(QString) = &Student::treat;
   // connect(t,f1, s, f2);    // 因?yàn)榘l(fā)生了函數(shù)重載,不能簡(jiǎn)單的用取地址符,編譯器判斷不了是哪個(gè)函數(shù),用函數(shù)指針
    ClassIsOver();  // 調(diào)用下課函數(shù)

    // 點(diǎn)擊一個(gè)按鈕, 觸發(fā)下課
    QPushButton *btn = new QPushButton("下課",this);
    this->resize(800,600);  // 重置窗口大小
    connect(btn,&QPushButton::clicked,this, &mywidget::ClassIsOver);
    // disconnect(btn,&QPushButton::clicked,this, &mywidget::ClassIsOver); // 斷開(kāi)鏈接
    /* 1、信號(hào)可以鏈接信號(hào)
     * 2、一個(gè)信號(hào)可以鏈接到多個(gè)槽函數(shù)
     * 3、多個(gè)信號(hào)可以鏈接到一個(gè)槽函數(shù)
     * 4、信號(hào)和槽函數(shù)的參數(shù)必須類型一一對(duì)應(yīng)(槽函數(shù)要接收信號(hào)的參數(shù))
     * 5、信號(hào)參數(shù)個(gè)數(shù)可以多于槽函數(shù)參數(shù)個(gè)數(shù),但是類型也要一一對(duì)應(yīng)
     */
    // QT5 6 向下兼容 QT4版本以前的信號(hào)和槽的鏈接方式
    connect(t,SIGNAL(hungry()), s, SLOT(treat(QString))); // 優(yōu)點(diǎn),直觀,缺點(diǎn),類型不做檢測(cè)
}

mywidget::~mywidget()
{

}

void mywidget::ClassIsOver()
{
    // emit t->hungry();
    emit t->hungry("宮保雞丁");
}
// student.cpp
#include "student.h"
# include <QDebug>
Student::Student(QObject *parent) : QObject(parent)
{

}
void Student::treat()
{
    qDebug() << "請(qǐng)老師吃飯";
}
void Student::treat(QString foodName)
{
    // qDebug() << "請(qǐng)老師吃 :" << foodName;    // 帶引號(hào),用toUtf8()先將它轉(zhuǎn)成QbyteArray類型,然后用data()在轉(zhuǎn)成char *類型
    qDebug() << "請(qǐng)老師吃 :" << foodName.toUtf8().data();
}

??main.cpp和teacher.cpp默認(rèn)即可。信號(hào)和槽使用時(shí)必須先鏈接后觸發(fā)信號(hào),才能響應(yīng)。

3.4 Lambda表達(dá)式

??Lambda表達(dá)式是C++11中用來(lái)定義并創(chuàng)建匿名的函數(shù)對(duì)象。實(shí)際上是一個(gè)匿名方法,用來(lái)聲明一個(gè)只在此次使用的匿名函數(shù)
[函數(shù)對(duì)象參數(shù)](操作符重載函數(shù)參數(shù))mutable->返回值(函數(shù)體)

  • 1、函數(shù)對(duì)象參數(shù):[],標(biāo)識(shí)一個(gè)lambda的開(kāi)始,這部分不能省略。函數(shù)對(duì)象參數(shù)是傳遞給編譯器自動(dòng)生成的函數(shù)對(duì)象類的構(gòu)迨函數(shù)。函數(shù)對(duì)象參數(shù)只能使用那些到定義Lambda 為止時(shí)Lambda所在作用范圍內(nèi)可見(jiàn)的局部變量(包括Lambda所在類的this)。函數(shù)對(duì)象參數(shù)有以下幾種形式:
參數(shù) 作用
沒(méi)有使用任何函數(shù)對(duì)象參數(shù)
= 函數(shù)體可以使用lambda所在作用范圍內(nèi)所有可見(jiàn)的局部變量
this 函數(shù)體可以使用lambda所在類中的成員變量
a 將a按值進(jìn)行傳遞
&a 將a按引用進(jìn)行傳遞
a, &b 將a按值傳遞,b按引用傳遞
=, &a, &b 除a b按引用傳遞外,其余值按值進(jìn)行傳遞
&, a, b 除a b按值進(jìn)行傳遞外,其余值按引用進(jìn)行傳遞

??其中=傳遞了包括Lambda所在類的this,并且是引用傳遞方式,相當(dāng)于編譯器自動(dòng)為我們引用傳遞了所有局部變量。按值進(jìn)行傳遞時(shí),函數(shù)體內(nèi)不能修改傳遞進(jìn)來(lái)的a的拷貝,因?yàn)槟J(rèn)情況下函數(shù)是const的。要修改傳遞進(jìn)來(lái)的a的拷貝,可以添加mutable修飾符。

  • 2、操作符重載函數(shù)參數(shù):標(biāo)識(shí)函數(shù)重載的()參數(shù),沒(méi)有參數(shù)時(shí),可以省略。參數(shù)可以用過(guò)按值傳遞和按引用兩種方式進(jìn)行傳遞。
  • 3、可修改標(biāo)識(shí)符:mutable聲明,這部分可以省略。按值傳遞函數(shù)對(duì)象參數(shù)時(shí),加上mutable修飾符,可以修改按值傳遞進(jìn)來(lái)的拷貝(注意僅僅是能修改拷貝, 而不是修改值本身)
  • 4、函數(shù)返回值:->返回值類型, 標(biāo)識(shí)函數(shù)返回值的類型,當(dāng)返回值為void,或者函數(shù)體中只有溢出return的地方(此時(shí)編譯器可以自動(dòng)推斷出返回值類型)時(shí),這部分可以省略。
  • 5、函數(shù)體: {},標(biāo)識(shí)函數(shù)的實(shí)現(xiàn),這部分不能省略,但函數(shù)體可以為空。
[capture](parameters)mutable->return-type
    {
        statement;
    }

??在空項(xiàng)目的基礎(chǔ)之上改變mywidget.cpp函數(shù):

#include "mywidget.h"
#include <QPushButton>
mywidget::mywidget(QWidget *parent)
    : QWidget(parent)
{
    // 利用lambda表達(dá)式,點(diǎn)擊按鈕,關(guān)閉窗口
    QPushButton *btn = new QPushButton("關(guān)閉", this);
    btn->move(100,100);
    connect(btn,&QPushButton::clicked,this, [=](){this->close();});
}

mywidget::~mywidget()
{
}

3.5 菜單欄工具欄的創(chuàng)建

??在空項(xiàng)目的基礎(chǔ)之上改變mywidget.cpp函數(shù):

#include "mainwindow.h"
#include <QPushButton>
#include <QMenuBar>
#include <QToolBar>
#include <QStatusBar>
#include <QDockWidget>
#include <QLabel>
#include <QTextEdit>

#include <QDebug>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    resize(1400,900);   // 重置窗口大小

    /********** 菜單欄創(chuàng)建 **********/
    QMenuBar *bar = menuBar();
    setMenuBar(bar);    // 將菜單欄放置到窗口中
    QMenu *fileMenu = bar->addMenu("文件");     // 創(chuàng)建菜單
    QMenu *editMenu = bar->addMenu("編輯");     // 創(chuàng)建菜單
    QAction *newAction = fileMenu->addAction("新建");
    fileMenu->addSeparator();        // 添加分隔線
    QAction *openAction = fileMenu->addAction("打開(kāi)");

    /********** 工具欄創(chuàng)建 **********/
    QToolBar *toolBar = new QToolBar(this); // 工具欄,可以有多個(gè)
    addToolBar(Qt::LeftToolBarArea, toolBar);
    toolBar->setAllowedAreas(Qt::LeftToolBarArea | Qt::RightToolBarArea);// 后期設(shè)置只允許左右???/span>
    toolBar->setFloatable(false);// 設(shè)置浮動(dòng)
    toolBar->setMovable(false);      // 允許移動(dòng)(總開(kāi)關(guān))
    toolBar->addAction(newAction);
    toolBar->addSeparator();
    toolBar->addAction(openAction);
    QPushButton *btn = new QPushButton("aaa",this);
    toolBar->addWidget(btn);

    /********** 狀態(tài)欄創(chuàng)建,最多一個(gè) **********/
    QStatusBar *stBar = statusBar();
    setStatusBar(stBar);
    QLabel *label = new QLabel("提示信息",this);
    stBar->addWidget(label);
    QLabel *label2 = new QLabel("右側(cè)提示信息",this);
    stBar->addPermanentWidget(label2);

    /********** 鉚接部件(浮動(dòng)窗口,可以有多個(gè))**********/
    QDockWidget *dockWidget = new QDockWidget("浮動(dòng)窗口",this);
    addDockWidget(Qt::BottomDockWidgetArea,dockWidget);
    dockWidget->setAllowedAreas(Qt::BottomDockWidgetArea | Qt::TopDockWidgetArea);   // 設(shè)置??繀^(qū)域,只允許上下

    /********** 設(shè)置中心部件,只能有一個(gè) **********/
    QTextEdit *edit = new QTextEdit(this);
    setCentralWidget(edit);

    /*總結(jié): 使用set加入窗口的部件智能有一個(gè),而add加入的能有多個(gè)*/
}

MainWindow::~MainWindow()
{
}

3.6 資源文件添加和UI界面使用

??在新建空白項(xiàng)目的第三步點(diǎn)擊generate form,生成項(xiàng)目后就會(huì)產(chǎn)生一個(gè).ui文件。UI界面可以直接拖拽控件,輸入文本,我們開(kāi)發(fā)窗口應(yīng)用就變得很方便。
qt界面開(kāi)發(fā),C++,qt

??在此界面的基礎(chǔ)上,創(chuàng)建文件,編輯,工具,幫助等菜單,菜單的一級(jí)目錄是無(wú)法鍵入中文的,只能輸入英文,然后在創(chuàng)建好的對(duì)象中將文本改成中文,建立完成后的文件如下。點(diǎn)擊項(xiàng)目添加文件,add new file -> Qt -> Qt resource file -> choose,然后更改文件名稱,一般設(shè)置為res,然后會(huì)在Resources底下生成一個(gè)res.qrc的文件。

qt界面開(kāi)發(fā),C++,qt

??將圖片復(fù)制到項(xiàng)目目錄底下的Image文件(所有圖片文件都放進(jìn)去),以資源編輯器的方式打開(kāi)res.qrc,添加前綴(可以直接使用默認(rèn)或者“/”),添加文件,使用“ : + 前綴名 + 文件名稱” 。mainwindow.cpp文件如下所示:

// mainwindow.cpp文件
#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
//    ui->actionnew->setIcon(QIcon("C:/Users/19080/Pictures/Camera Roll/文件圖標(biāo).JPEG") );	// 絕對(duì)路徑
    // 使用添加Qt資源文件
    ui->actionnew->setIcon(QIcon(":Image\\fileIcon.JPEG") );	
    ui->actionopen->setIcon(QIcon(":Image\\Luffy.jpg") );
}

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

3.7 對(duì)話框

3.7.1 模態(tài)和非模態(tài)

??mainwindow.cpp文件如下所示:


#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDialog>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    // 點(diǎn)擊新建按鈕 彈出一個(gè)對(duì)話框
    connect(ui->actionnew,&QAction::triggered,[=](){
    /* 對(duì)話框 分類
     * 模態(tài)對(duì)話框(不可以對(duì)其他窗口進(jìn)行操作) 非模態(tài)對(duì)話框則相反
     */
        /*  模態(tài)創(chuàng)建 阻塞   */
//     QDialog dig(this);
//     dig.resize(200,100);
//     dig.exec();
//     qDebug() <<"模態(tài)對(duì)話框彈出";
    /*  非模態(tài)創(chuàng)建   */
     QDialog *dig2 = new QDialog(this);
     dig2->resize(200,100);
     dig2->show();
     dig2->setAttribute(Qt::WA_DeleteOnClose);  // 55號(hào)屬性
     qDebug() << "非模態(tài)對(duì)話框彈出";
    });

}

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

3.7.2 消息對(duì)話框

??目前Qt內(nèi)置對(duì)話框有:

名稱 作用
QColorDialog 選擇顏色
QFileDialog 選擇文件或者目錄
QFontDialog 選擇字體
QInputDialog 允許用戶輸入一個(gè)值,并將值返回
QMessageBox 模態(tài)對(duì)話框,用于顯示信息、詢問(wèn)信息等等
QPageSetupDialog 為打印機(jī)提供紙張相關(guān)的選項(xiàng)
QPrintDialog 打印機(jī)配置
QPrintPreviewDialog 打印預(yù)覽
QProgressDialog 顯示操作過(guò)程

??mainwindow.cpp文件如下所示,其中QMessageBox::question的返回值是QMessageBox::StandardButton類型,我們就可以利用if語(yǔ)句去判斷返回值是否為QMessageBox::Save,從而進(jìn)一步做其他操作。

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDialog>
#include <QMessageBox>
#include <QDebug>
#include <QColorDialog>
#include <QFileDialog>
#include <QFontDialog>
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    connect(ui->actionnew,&QAction::triggered,[=](){
    // 錯(cuò)誤對(duì)話框
//    QMessageBox::critical(this, "critical", "錯(cuò)誤");
    // 信息對(duì)話框
//    QMessageBox::information(this, "info", "信息");
    // 提問(wèn)對(duì)話框 參數(shù)1:父類,參數(shù)2:title, 參數(shù)3:提示信息, 參數(shù)4:按鍵選項(xiàng), 參數(shù)5: 默認(rèn)選項(xiàng)(關(guān)聯(lián)回車選項(xiàng))
//    if(QMessageBox::Save == QMessageBox::question(this, "ques", "提問(wèn)",QMessageBox::Save|QMessageBox::Cancel,QMessageBox::Save))
//    {
//        qDebug() << "選擇的是保存";
//    }
//    else
//    {
//        qDebug() << "選擇的是取消";
//    }
    // 警告對(duì)話框
    //QMessageBox::warning(this,"warning","警告");

    // 其他標(biāo)準(zhǔn)對(duì)話框
    // 顏色對(duì)話框
//    QColor color = QColorDialog::getColor(QColor(255, 0, 0));
//    qDebug() << "  r = " << color.red() << "  g = "<< color.green() << "  b = " << color.blue();
    // 文件對(duì)話框 參數(shù)1: 父類, 參數(shù)2: 對(duì)話框標(biāo)題  參數(shù)3:默認(rèn)打開(kāi)路徑,參數(shù)4:過(guò)濾器(僅能選取該類型文件) 返回值是選取文件路徑
//    QString str= QFileDialog::getOpenFileName(this, "打開(kāi)文件", "C:\\Users\\19080\\Desktop", "(*.txt)");
//    qDebug() << str;
    // 字體對(duì)話框
        bool flag;
    QFont font = QFontDialog::getFont(&flag, QFont("華文云彩",  36) );
    qDebug() <<" 字體: "<< font.family() <<" 大小:"<< font.pointSize()<< "是否加粗:"<< font.bold() << "是否傾斜:"<< font.italic();
    });

}

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

3.8 設(shè)計(jì)登錄界面

??首先我們現(xiàn)在UI界面創(chuàng)建如下控件,用戶名和密碼用Label控件,輸入框用Line Edit控件,登錄和退出用PushButton控件。

qt界面開(kāi)發(fā),C++,qt

??然后在左側(cè)工具欄Containers中選擇Widget控件,將用戶名、密碼和輸入框拖入Widget中選擇,在上方工具欄中選擇柵格布局(適用于多行多列的,如果是單行或單列可以選擇水平布局或垂直布局),布局之后就變得更整齊。登錄和退出就選擇水平布局。為了在窗口縮放是保持各個(gè)空間的相對(duì)位置不變,可以加入Spacers控件(也可以不加),其效果于彈簧。

qt界面開(kāi)發(fā),C++,qt

??登錄界面一般開(kāi)發(fā)時(shí)就確定大小,我們找到MainWindow->sizePolicy->水平和垂直策略都選擇Fixed,然后將minnumSize和maxiumSize都選擇固定的尺寸(具體數(shù)值任意,大小合適即可)。操作完畢后窗口大小就固定下來(lái)。
??最后修改窗口名稱,選中密碼對(duì)應(yīng)的編輯框,QLineEdit->echoMode->Password(輸入密碼的編程一個(gè)個(gè)黑圈圈),到目前為止我們將登錄窗口的UI界面設(shè)計(jì)完畢,但是具體的功能還需要底層代碼才能實(shí)現(xiàn)。
qt界面開(kāi)發(fā),C++,qt

3.9 各類控件

3.9.1 按鈕組

??Qt的UI設(shè)計(jì)界面的按鈕組有:PushButton,ToolButton, Radio Button, Check Box等等。
??ToolButton建立后,可以添加圖片和修改文本,選擇Icon->選擇資源文件(前面部分有介紹),然后選擇QToolButton->autoRaise,其效果是當(dāng)光標(biāo)移動(dòng)到該按鈕時(shí),按鈕自動(dòng)高光亮起。
??依次創(chuàng)建4個(gè)Radio Button,分別命名為男 女, 已婚, 未婚。然后添加Group Box, 將男女添加今一個(gè)Group Box, 修改文本為性別。同理,已婚和未婚這兩個(gè)Radio Button為另外一組。
??創(chuàng)建4個(gè)Check Box依次修改文本,放入Group Box中,設(shè)置垂直布局。然后在添加一個(gè)ListWidget,在預(yù)覽圖中顯示為白色框。
qt界面開(kāi)發(fā),C++,qt

??在mainwindow.cpp中輸入如下代碼,形成代碼和界面的聯(lián)動(dòng):

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    // 設(shè)置單選按鈕 默認(rèn)男選中
    ui->radioButton->setChecked(true);

    // 選中女后打印信息
    connect(ui->radioButton_2, &QRadioButton::clicked,[=](){
        qDebug() << "選中了女性按鈕";
    });

    // 多選按鈕  2:選中  1:半選中  0:未選中
    // 信號(hào)為stateChanged, 槽函數(shù)為lambda表達(dá)式, 信號(hào)的參數(shù)會(huì)自動(dòng)傳給槽函數(shù)
    connect(ui->checkBox_4, &QCheckBox::stateChanged,[=](int state){
        qDebug() << state;
    });

    // 利用listWidget寫詩(shī)
    QListWidgetItem *item = new QListWidgetItem("窗前明月光");
    // 將一行詩(shī)放到listWidget控件中
    ui->listWidget->addItem(item);
    item->setTextAlignment(Qt::AlignHCenter);   // 設(shè)置為水平居中
    // QStringList     QList<QString>
    QStringList list;
    list << "疑是地上霜"<< "舉頭望明月"<<"低頭思故鄉(xiāng)"; // 將這幾句詩(shī)加入鏈表類中
    ui->listWidget->addItems(list);     //  這種方法無(wú)法設(shè)置對(duì)齊格式
}

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

3.9.2 QTreeWidget和QTableWidget控件

??QTreeWidget控件代碼如下:

#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    // treeWidget樹(shù)控件使用

    // 設(shè)置水平頭
    // 從下面兩行代碼可以看出,str相當(dāng)于一個(gè)string類型的列表(例如,vector<string>) <<操作符相當(dāng)于 append()函數(shù)的作用
//    QStringList str = QStringList()<<"英雄"<<"英雄介紹";
//    qDebug() << str;
    ui->treeWidget->setHeaderLabels (QStringList()<<"卡牌類型"<<"卡牌介紹");
    QTreeWidgetItem *monster = new QTreeWidgetItem(QStringList()<< " 怪獸");
    QTreeWidgetItem *magic = new QTreeWidgetItem(QStringList()<< " 魔法");
    QTreeWidgetItem *trap = new QTreeWidgetItem(QStringList()<< " 陷阱");

    // 加載頂層節(jié)點(diǎn)
    ui->treeWidget->addTopLevelItem(monster);
    ui->treeWidget->addTopLevelItem(magic);
    ui->treeWidget->addTopLevelItem(trap);

    // 加載子節(jié)點(diǎn)
    QStringList m1 = QStringList()<< "增殖的G"<< "效果怪獸,每次對(duì)方對(duì)怪獸的特殊召喚成功,自己從卡組抽1張";
    QTreeWidgetItem *monster1 = new QTreeWidgetItem(m1);
    monster->addChild(monster1);

    QStringList m2 = QStringList()<< "效果遮蒙者"<< "效果怪獸,以對(duì)方場(chǎng)上1只效果怪獸為對(duì)象,其效果直到回合結(jié)束時(shí)無(wú)效。";
    QTreeWidgetItem *monster2 = new QTreeWidgetItem(m2);
    monster->addChild(monster2);

    QStringList ma1 = QStringList()<< "強(qiáng)欲之壺"<< "通常魔法,從卡組抽兩張牌";
    QTreeWidgetItem *magic1 = new QTreeWidgetItem(ma1);
    magic->addChild(magic1);

    QStringList ma2 = QStringList()<< "天使的施舍"<< "通常魔法,從卡組抽三張,然后丟棄兩張手牌";
    QTreeWidgetItem *magic2 = new QTreeWidgetItem(ma2);
    magic->addChild(magic2);

    QStringList t1 = QStringList()<< "技能抽取"<< "永續(xù)陷阱,能夠使場(chǎng)上表側(cè)表示的怪獸卡效果無(wú)效";
    QTreeWidgetItem *trap1 = new QTreeWidgetItem(t1);
    trap->addChild(trap1);

    QStringList t2 = QStringList()<< "王宮的敕命"<< "永續(xù)陷阱,能夠使場(chǎng)上的魔法卡效果無(wú)效";
    QTreeWidgetItem *trap2 = new QTreeWidgetItem(t2);
    trap->addChild(trap2);
}

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

??效果圖:

qt界面開(kāi)發(fā),C++,qt

??QTableWidget控件

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    // TableWidget控件
    // 設(shè)置列數(shù),一定要設(shè)置,不然會(huì)出現(xiàn)未知錯(cuò)誤
    ui->tableWidget->setColumnCount(3);

    // 設(shè)置水平表頭
    ui->tableWidget->setHorizontalHeaderLabels(QStringList()<<"姓名"<<"性別"<<"年齡");

    // 設(shè)置行數(shù)
    ui->tableWidget->setRowCount(5);

    // 設(shè)置正文
    //ui->tableWidget->setItem(0,0,new QTableWidgetItem("張三"));
    QStringList nameList = QStringList()<<"李大"<<"柳二"<<"張三"<<"劉四"<<"王五";
    QStringList sexList = QStringList()<<"男"<<"男"<<"女"<<"女"<<"女";
    for(int i=0;i<5;i++)
    {
        int col = 0;
        ui->tableWidget->setItem(i,col++,new QTableWidgetItem(nameList[i]));
        ui->tableWidget->setItem(i,col++,new QTableWidgetItem(sexList.at(i)));
        ui->tableWidget->setItem(i,col++,new QTableWidgetItem(QString::number(i+18)));
    }
}

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

??效果圖:

qt界面開(kāi)發(fā),C++,qt

3.9.3 其他控件

??主要包括了scroll area、 tool box、tab widget、stacked widget等控件。其中scroll area 是滾動(dòng)條控件,toolbox是列表頁(yè)面(例如QQ的聯(lián)系人列表),tab widget是類似網(wǎng)頁(yè)頁(yè)面的控件。stacked widget是??丶梢詫⒁陨先齻€(gè)頁(yè)面全部放到??丶校缓髮?shí)現(xiàn)多個(gè)頁(yè)面的切換。代碼中還包括了combo box下拉框,QLabel的簡(jiǎn)單使用。其中,QLabel可以用作顯示圖片,播放動(dòng)態(tài)圖,視頻等等。

#include "widget.h"
#include "ui_widget.h"
#include <QPushButton>
#include <QMovie>
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    // stacked Widget??丶氖褂?/span>
    // 默認(rèn)定位
    ui->stackedWidget->setCurrentIndex(0);

    // scroll area 按鈕
    connect(ui->btn_scroll,&QPushButton::clicked, [=](){
        ui->stackedWidget->setCurrentIndex(0);
    });
    // toolBox 按鈕
    connect(ui->btn_toolBox,&QPushButton::clicked, [=](){
        ui->stackedWidget->setCurrentIndex(1);
    });
    // tabWidge 按鈕
    connect(ui->btn_tabWidget,&QPushButton::clicked, [=](){
        ui->stackedWidget->setCurrentIndex(2);
    });

    // combo box 下拉框
    ui->comboBox->addItem("奔馳");
    ui->comboBox->addItem("寶馬");
    ui->comboBox->addItem("拖拉機(jī)");

    // 點(diǎn)擊按鈕選中拖拉機(jī)
    connect(ui->pushButton_16,&QPushButton::clicked, [=](){
        // ui->comboBox->setCurrentIndex(2);
        ui->comboBox->setCurrentText("拖拉機(jī)");    // 兩句代碼效果一樣
    });
    // 利用QLabel顯示圖片
    ui->imaLabel->setPixmap(QPixmap(":/Image/fileIcon.JPEG").scaled(ui->imaLabel->size()));

    //利用QLabel顯示gif動(dòng)態(tài)圖片
    QMovie *movie = new QMovie(":/Image/picaqu.gif");
    movie->setScaledSize(ui->movieLabel->size());
    ui->movieLabel->setMovie(movie);
    // 播放動(dòng)圖
    movie->start();
}

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

??效果圖:
qt界面開(kāi)發(fā),C++,qt

3.9.4 自定義控件封裝

??建立一個(gè)自定義的控件,將QSpinBox和QSlider聯(lián)動(dòng)起來(lái):QSpinBox移動(dòng),QSlider跟著移動(dòng),QSlider跟著移動(dòng),QSpinBox也跟著移動(dòng)。

??項(xiàng)目文件點(diǎn)擊->新建->Qt->設(shè)計(jì)師界面->widget,然后修改文件名(SmallWidget)。在smallwidget.up界面中添加,QSpinBox和QSlider兩個(gè)控件:
qt界面開(kāi)發(fā),C++,qt
??右鍵SmallWidget窗口->提升為->添加->提升,成功以后,widget類底下就會(huì)包含SmallWidget類。
??修改smallwidget.cpp文件:

// smallwidget.cpp文件
#include "smallwidget.h"
#include "ui_smallwidget.h"

SmallWidget::SmallWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::SmallWidget)
{
    ui->setupUi(this);
    // QSpinBox移動(dòng),QSlider跟著移動(dòng)
    void (QSpinBox:: *spSignal)(int) = &QSpinBox::valueChanged; // valueChanged有重載版本,因此需要確定輸入?yún)?shù)是哪種版本的,這里需要的是int輸入
    connect(ui->spinBox, spSignal, ui->horizontalSlider, &QSlider::setValue);
    // QSlider跟著移動(dòng) QSpinBox移動(dòng)
    connect(ui->horizontalSlider, &QSlider::valueChanged, ui->spinBox, &QSpinBox::setValue);
}

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

3.10 鼠標(biāo)和定時(shí)器事件以及事件分發(fā)器、過(guò)濾器

??添加myLabel類->C+±>C++Class,父類選擇為QWidget,因?yàn)樾陆?xiàng)目窗口能夠選擇父類有限,這里我們就選擇QWidget類,項(xiàng)目文件建好后,修改mylabel.h文件中include頭文件和父類,mylabel.cpp中構(gòu)造函數(shù)的父類,全部修改為QLabel。

??進(jìn)入U(xiǎn)I界面,拖拽一個(gè)Label控件,修改為合適大小,文字刪除,此時(shí)控件消失,為了方便觀察,我們?cè)O(shè)置控件的邊框?yàn)锽ox類型,屬性頁(yè)面QFrame->frameShape->Box,如下圖所示。

qt界面開(kāi)發(fā),C++,qt

??UI界面的設(shè)置創(chuàng)建兩個(gè)label控件,用來(lái)顯示定時(shí)器數(shù)字。定時(shí)器主要使用到timerEvent(QTimerEvent *ev)函數(shù),多個(gè)定時(shí)器之間用timeId來(lái)區(qū)分。

qt界面開(kāi)發(fā),C++,qt

??多個(gè)事件之間通過(guò)bool event(QEvent *ev)來(lái)進(jìn)行事件分發(fā),返回值是bool類型,如果返回值是true代表用戶要處理這個(gè)事件,不向下分發(fā)事件。

qt界面開(kāi)發(fā),C++,qt

// mylabel.h文件
#ifndef MYLABEL_H
#define MYLABEL_H
#include <QLabel>
class myLabel : public QLabel
{
public:
    explicit myLabel(QWidget *parent = nullptr);
    // 聲明
    // 鼠標(biāo)進(jìn)入事件
    void enterEvent(QEvent *event);
    // 鼠標(biāo)離開(kāi)事件
    void leaveEvent(QEvent *);
    // 鼠標(biāo)按下事件
    void mousePressEvent(QMouseEvent *event);
    // 鼠標(biāo)釋放事件
    void mouseReleaseEvent(QMouseEvent *event);
    // 鼠標(biāo)移動(dòng)事件
    void mouseMoveEvent(QMouseEvent *event);
    // 通過(guò)event事件分發(fā)器攔截 鼠標(biāo)按下事件
    bool event(QEvent *e);
signals:

};
#endif // MYLABEL_H
// widget.h文件
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
    Q_OBJECT
public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
    // 定時(shí)器事件
    void timerEvent(QTimerEvent *);
    int id1;    // 定時(shí)器1的唯一標(biāo)識(shí)
    int id2;    // 定時(shí)器2的唯一標(biāo)識(shí)
    // 重寫事件過(guò)濾器的時(shí)間
    bool eventFilter(QObject *obj, QEvent *e);
private:
    Ui::Widget *ui;
};
#endif // WIDGET_H
// mylabe.cpp文件
#include "mylabel.h"
#include <QDebug>
#include <QMouseEvent>
myLabel::myLabel(QWidget *parent) : QLabel(parent)
{
    // 設(shè)置鼠標(biāo)追蹤
    setMouseTracking (true);      // 原來(lái)是點(diǎn)擊后鼠標(biāo)移動(dòng)才能觸發(fā),現(xiàn)在只要鼠標(biāo)移動(dòng)就能觸發(fā)鼠標(biāo)移動(dòng)事件。
}
// 鼠標(biāo)進(jìn)入事件
void myLabel::enterEvent(QEvent *event)
{
    qDebug() << "鼠標(biāo)進(jìn)入";
}
// 鼠標(biāo)離開(kāi)事件
void myLabel::leaveEvent(QEvent *)
{
    qDebug()<< "鼠標(biāo)離開(kāi)";
}
// 鼠標(biāo)按下事件
void myLabel::mousePressEvent(QMouseEvent *event)
{
    // 要求:當(dāng)鼠標(biāo)左鍵按下時(shí),打印信息,右鍵按下不打印
    if(event->button() == Qt::LeftButton)
    {
        QString str = QString("鼠標(biāo)按下了 x = %1, y = %2, globalx = %3, globaly = %4").arg(event->x()).arg (event->y()).arg (event->globalX()).arg (event->globalY());
        qDebug()<< str;
    }
}
// 鼠標(biāo)釋放事件
void myLabel::mouseReleaseEvent(QMouseEvent *event)
{
    if(event->button() == Qt::LeftButton)
    {
        qDebug()<< "鼠標(biāo)釋放";
    }
}
// 鼠標(biāo)移動(dòng)事件
void myLabel::mouseMoveEvent(QMouseEvent *event)
{
    qDebug()<< "鼠標(biāo)移動(dòng)";
//    if(event->buttons() & Qt::LeftButton) // &位與操作,buttons用于同時(shí)按下多個(gè)按鈕,只要按下的按鈕中包含左鍵,執(zhí)行下面的操作。
//    {
//        qDebug()<< "鼠標(biāo)移動(dòng)";
//    }
}
// 通過(guò)event事件分發(fā)器攔截 鼠標(biāo)按下事件
bool myLabel::event(QEvent *e)
{
    // 如果是鼠標(biāo)按下,在event中做攔截操作,也就是說(shuō)在這一層做處理,后面的 鼠標(biāo)按下 相關(guān)代碼就不會(huì)觸發(fā)
    if(e->type() == QEvent::MouseButtonPress)
    {
        QMouseEvent *ev = static_cast<QMouseEvent *>(e);        // static_cast是C++的強(qiáng)制類型轉(zhuǎn)換,大精度類型轉(zhuǎn)小精度類型,有損
        QString str = QString("Event函數(shù)中,鼠標(biāo)按下了 x = %1, y = %2, globalx = %3, globaly = %4").arg(ev->x()).arg (ev->y()).arg (ev->globalX()).arg (ev->globalY());
        qDebug() << str;
        return true;    // true代表用戶自己處理這個(gè)事件,不向下分發(fā)
    }
    // 其他事件交給父類處理, 其余事件都正常傳給后面的代碼處理
    return QLabel::event(e);
}
// widget.cpp文件
#include "widget.h"
#include "ui_widget.h"
#include <QTimer>
#include <QMouseEvent>
#include <QDebug>
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    id1 = startTimer(1000);   // 啟動(dòng)計(jì)時(shí)器,參數(shù)1:間隔,單位毫秒
    id2 = startTimer(2000);

    // 定時(shí)器的第二種方式
    QTimer *timer = new QTimer(this);
    // 啟動(dòng)定時(shí)器
    timer->start(500);
    connect(timer, &QTimer::timeout, [=](){
        static int num3 = 1;
            // label4 每隔0.5秒+1
            ui->label_4->setText(QString::number(num3++));
    });

    // 點(diǎn)擊按鈕暫停定時(shí)器,第三個(gè)暫停
    connect(ui->btn1, &QPushButton::clicked, [=](){
        timer->stop();
    });

    // 給label 安裝事件過(guò)濾器, 實(shí)際上是一個(gè)比event攔截器更高級(jí)的攔截器
    // 第一步
    ui->label->installEventFilter(this);
}
// 第二步 重寫 eventfiler事件
bool Widget::eventFilter(QObject *obj, QEvent *e)
{
    if(obj == ui->label)
    {
        if(e->type() == QEvent::MouseButtonPress)
        {
            QMouseEvent *ev = static_cast<QMouseEvent * >(e);
            QString str = QString("事件過(guò)濾器中,鼠標(biāo)按下了 x = %1, y = %2, globalx = %3, globaly = %4").arg(ev->x()).arg (ev->y()).arg (ev->globalX()).arg (ev->globalY());
            qDebug() << str;
            return true;    // true代表用戶自己處理這個(gè)事件,不向下分發(fā)
         }
    }
    // 其他事件交給父類處理, 其余事件都正常傳給后面的代碼處理
    return QWidget::eventFilter(obj, e);
}

// 定時(shí)器事件
void Widget::timerEvent(QTimerEvent *ev)
{
    if(ev->timerId() == id1)
    {
        static int num1 = 1;
        ui->label_2->setText(QString::number(num1++));
    }
    if(ev->timerId() == id2)
    {
        static int num2 = 1;
        ui->label_3->setText(QString::number(num2++));
    }
}
Widget::~Widget()
{
    delete ui;
}

3.11 繪畫

3.11.1 繪畫設(shè)置

??這里主要介紹的是畫類操作,畫直線,畫圓,畫矩形等等,畫筆,毛刷等等設(shè)置,widget.cpp文件如下,此外,還需要在widget.h文件聲明函數(shù)void paintEvent(QPaintEvent *event)。

// widget.cpp文件
#include "widget.h"
#include "ui_widget.h"
#include <QPainter>
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    // 點(diǎn)擊移動(dòng)按鈕,移動(dòng)圖片 ,paintEvent函數(shù)默認(rèn)會(huì)調(diào)用一次,然后就是調(diào)用repaint函數(shù),即重新繪畫函數(shù)
    connect (ui->pushButton, &QPushButton::clicked, [=](){
        // 手動(dòng)調(diào)用繪圖事件函數(shù),實(shí)際上是調(diào)用repaint函數(shù)
        PosX += 20;		// 需要在widget.h中聲明, int PosX = 150;
        update();
    });

}
// 繪圖事件
void Widget::paintEvent(QPaintEvent *event)
{
//    // 實(shí)例化畫家對(duì)象, this制定繪圖設(shè)備
//    QPainter painter(this);
//    //  設(shè)置畫筆
//    QPen pen(QColor(255,0,0));      // 設(shè)置顏色
//    pen.setWidth (5);               // 設(shè)置寬度
//    pen.setStyle (Qt::DotLine);     // 設(shè)置風(fēng)格
//    painter.setPen (pen);
//    // 設(shè)置畫刷
//    QBrush brush(QColor(0,255,0));
//    brush.setStyle (Qt::Dense1Pattern);
//    painter.setBrush (brush);
//    // 畫了一條線(兩個(gè)點(diǎn)確定)
//    painter.drawLine(QPoint(0,0),QPoint(100,100));
//    // 畫橢圓圓,圓心和長(zhǎng)短軸焦點(diǎn)a,b確定 a=b就是圓
//    painter.drawEllipse (QPoint(100,100),50,50);
//    // 畫矩形
//    painter.drawRect (QRect(20,20,50,50));
//    // 畫文字
//    painter.drawText (QRect(10,200,150,50),"好好學(xué)習(xí),天天向上");
    ****高級(jí)設(shè)置*******/
//    QPainter painter(this);
//    painter.drawEllipse (QPoint(200,200),100,100);
//    //  設(shè)置 抗鋸齒能力,即畫的仔細(xì)一點(diǎn),毛邊少一點(diǎn),但是效率低一點(diǎn)
//    painter.setRenderHint (QPainter::Antialiasing);
//    painter.drawEllipse (QPoint(400,200),100,100);
//    // 畫矩形
//    painter.drawRect (QRect(20,20,50,50));
//    painter.translate (100,0);  // 畫家從0,0開(kāi)始作畫,變成從100,0開(kāi)始作畫
//    // 保存畫家狀態(tài)
//    painter.save();
//    painter.drawRect (QRect(20,20,50,50));
//    // 還原畫家保存狀態(tài)
//    painter.restore ();
//    painter.drawRect (QRect(20,20,50,50));

    / ******* 利用畫家調(diào)用圖片資源  **** //
    QPainter painter(this);

    // 如果超過(guò)屏幕寬度 ,從0開(kāi)始
    if(PosX > this->width())
    {
        PosX = 0;
    }
    painter.drawPixmap(PosX,20,QPixmap(":/Image/Luffy.jpg"));
}

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

qt界面開(kāi)發(fā),C++,qt

3.11.2 繪圖設(shè)備

??主要有QPixmap,QPicture,QImage三種,需要在widget.h文件聲明函數(shù)void paintEvent(QPaintEvent *event)

#include "widget.h"
#include "ui_widget.h"
#include <QPixmap>
#include <QPainter>
#include <QPicture>
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
//   //
//    // Pixmap繪圖設(shè)備,專門為平臺(tái)做了顯示的優(yōu)化
//    QPixmap pix(300,300); // 說(shuō)明畫紙大小

//    // 填充背景色
//    pix.fill(Qt::white);
//    // 聲明畫家
//    QPainter painter(&pix);
//    painter.setPen(QPen(Qt::green));
//    painter.drawEllipse(QPoint(150,150),100,100);

//    // 保存
//    pix.save("D:\\software\\QT\\QT_Project\\qtDemo10\\pix.png");

 // ///
//    // QImage 繪圖設(shè)備 可以對(duì)每個(gè)像素進(jìn)行訪問(wèn)
//    QImage img(300,300, QImage::Format_RGB32);
//    img.fill(Qt::white);

//    QPainter painter(&img);
//    painter.setPen(QPen(Qt::blue));
//    painter.drawEllipse(QPoint(150,150),100,100);

//    // 保存
//    img.save("D:\\software\\QT\\QT_Project\\qtDemo10\\img.png");

 
    // QPicture 繪圖設(shè)備,可以記錄和重現(xiàn)繪圖指令
    QPainter painter;
    QPicture pic;
    painter.begin(&pic);    // 開(kāi)始往pic上畫畫
    painter.setPen(QPen(Qt::blue));
    painter.drawEllipse (QPoint(150,150),100,100);
    painter.end();  // 結(jié)束畫畫

    // 保存到磁盤
    pic.save("D:\\software\\QT\\QT_Project\\qtDemo10\\pic.hyf");
    // hyf是博主的姓名縮寫,在文件資源管理器中是無(wú)法打開(kāi)這個(gè)圖片的
    // 我們?cè)诶L圖事件中使用load函數(shù)可以打開(kāi),準(zhǔn)確來(lái)說(shuō)是重新繪制,因此pic保存的不是圖片本身而是繪制圖片的指令
}
// 繪圖事件
void Widget::paintEvent(QPaintEvent *event)
{
//    // 利用QImage 對(duì)像素進(jìn)行修改
//    QPainter painter(this);
//    QImage img;
//    img.load(":/Image/fileIcon.JPEG");

//    // 修改像素點(diǎn)
//    for(int i=50; i<100; i++)
//    {
//        for (int j=50;j<100;j++)
//        {
//            QRgb value = qRgb(255,0,0);
//            img.setPixel(i,j,value);
//        }
//    }
//    painter.drawImage(0,0,img);

    // 重現(xiàn)QPicture繪圖指令
    QPainter painter(this);
    QPicture pic;
    pic.load("D:\\software\\QT\\QT_Project\\qtDemo10\\pic.hyf");
    painter.drawPicture(0,0,pic);
}
Widget::~Widget()
{
    delete ui;
}

3.12 文件讀取

??文件讀取是主要注意打開(kāi)文件,也要關(guān)閉文件,此外,QFile默認(rèn)是UTF-8格式類型。widget.cpp文件如下所示:

#include "widget.h"
#include "ui_widget.h"
#include <QFileDialog>
#include <QFile>
#include <QTextCodec>
#include <QFileInfo>
#include <QDebug>
#include  <QDateTime>
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    connect (ui->pushButton, &QPushButton::clicked, [=](){
        QString path = QFileDialog::getOpenFileName (this,"打開(kāi)文件","C:/Users/19080/Desktop");
        // 將路徑放到lineEdit中
        ui->lineEdit->setText(path);

        // 編碼格式類
        QTextCodec *codec = QTextCodec::codecForName("gbk");

        // 讀取內(nèi)容,放入到textEdit中
        // QFile默認(rèn)支持的格式是UTF-8
        QFile file(path);   // 參數(shù)就是file path
        file.open(QIODevice::ReadOnly); // 設(shè)置打開(kāi)方式
        //QByteArray array = file.readAll();

        QByteArray array;
        while( !file.atEnd() )
        {
            array += file.readLine();
        }

        // 將讀取的數(shù)據(jù)放入到text Edit中
        ui->textEdit->setText(array);
        //ui->textEdit->setText(codec->toUnicode(array));
        file.close();   // 對(duì)文件對(duì)象進(jìn)行關(guān)閉

         文件寫入操作
        file.open(QIODevice::Append);   // 追加的方式寫入
        file.write("123456789");
        file.close();

           QFileInfo        ///
        // QFileInfo 文件信息類
        QFileInfo info(path);
        qDebug() << "大小(字節(jié)):" << info.size()<< "后綴名:"<< info.suffix()<< "文件名稱:"<< info.fileName() <<"文件路徑:"<< info.filePath();
        qDebug() << "文件創(chuàng)建日期: "<< info.created().toString ("yyyy/MM/dd hh:mm:ss");  // 按格式輸出 yyyy/MM/dd hh:mm:ss
        qDebug() << "文件創(chuàng)建日期: "<< info.lastModified().toString ("yyyy/MM/dd hh:mm:ss");
    });
}
Widget::~Widget()
{
    delete ui;
}

四、翻金幣小游戲

4.1 出現(xiàn)的問(wèn)題

??如果沒(méi)有素材可以從網(wǎng)上找,圖片資源都可以根據(jù)實(shí)際變化,不是唯一的。資源網(wǎng)站這里推薦阿里的圖標(biāo)庫(kù)。
??博主在寫這個(gè)代碼的過(guò)程中出現(xiàn)了一些錯(cuò)誤,第一個(gè)錯(cuò)誤博主沒(méi)有解決,將第二個(gè)錯(cuò)誤解決后,第一個(gè)就沒(méi)有出現(xiàn)了。第二個(gè)和第三個(gè)錯(cuò)誤在頭文件前面加上Q_OBJECT成員變量,加在public前面,問(wèn)題解決參考自博客No Q_OBJECT in the class with the signal錯(cuò)誤解決辦法,然后在.pro文件末尾加上空格重新編譯。

error: 'QtPrivate::QFunctorSlotObject<Func, N, Args, R>::QFunctorSlotObject(Func) [with Func = MainScene::MainScene(QWidget*)::<lambda()>; int N = 0; Args = QtPrivate::List<>; R = void]', declared using local type 'MainScene::MainScene(QWidget*)::<lambda()>', is used but never defined [-fpermissive]
         explicit QFunctorSlotObject(Func f) : QSlotObjectBase(&impl), function(std::move(f)) {}
                  ^~~~~~~~~~~~~~~~~~
 error: static assertion failed: No Q_OBJECT in the class with the signal
 #  define Q_STATIC_ASSERT_X(Condition, Message) static_assert(bool(Condition), Message)
                                                ^
error: undefined reference to `vtable for

4.2 源碼下載

??這里直接給大家分享一下成品,用百度網(wǎng)盤給出,步驟博主就不在一一介紹。
鏈接:https://pan.baidu.com/s/1QGdOGuyTYMGfSgi81O71vw?pwd=zajg
提取碼:zajg

4.3 NSIS打包程序

??當(dāng)我們寫好程序后將編譯運(yùn)行按鈕中的debug輸出改為release輸出,然后得到一個(gè)發(fā)布版本的.exe程序,如圖所示:

qt界面開(kāi)發(fā),C++,qt

??我們將他單獨(dú)拎出來(lái)放到桌面的release文件夾(自己命名的空文件夾都可以)中,然后找到對(duì)應(yīng)編譯器的命令行窗口,如下圖所示,博主這里有兩個(gè)編譯器,博主的是MinGW 64-bit的。然后輸入windeployqt.exe CoinFlip.exe,按回車鍵,程序打包成功,之前的release文件就多了一些生成的打包文件。

windeployqt.exe CoinFlip.exe

qt界面開(kāi)發(fā),C++,qt
qt界面開(kāi)發(fā),C++,qt

??windeployqt.exe文件實(shí)際上是Qt編譯器提供的打包成window程序的可執(zhí)行文件,可以在對(duì)應(yīng)編譯器的bin文件中找到。

qt界面開(kāi)發(fā),C++,qt

??這里需要注意不能使用普通的命令行窗口執(zhí)行這個(gè)命令,會(huì)出現(xiàn)無(wú)法找到入口的問(wèn)題。

qt界面開(kāi)發(fā),C++,qt

??然后我們使用HM NIS Edit軟件進(jìn)行Setup.exe文件的打包,需要配合NSIS軟件一起使用。
??NSIS是"Nullsoft 腳本安裝系統(tǒng)"(Nullsoft scriptable Installation System)的縮寫,它是是一個(gè)免費(fèi)的win32安裝、卸載系統(tǒng),可以很方便的打包windows應(yīng)用程序。它的特點(diǎn):腳本簡(jiǎn)潔高效;系統(tǒng)開(kāi)銷少;支持安裝、卸載、系統(tǒng)設(shè)置、解壓文件等功能。這里博主直接給出NSIS下載地址和HM NIS Edit下載地址,嫌麻煩的也可以用博主的百度網(wǎng)盤地址下載,鏈接:https://pan.baidu.com/s/1FrLENkVtB-B2lGslqw33bw?pwd=wybc
提取碼:wybc。
??參考博客 手把手教N(yùn)IS Edit安裝向?qū)У氖褂谩.?dāng)順著教程做到這一步的時(shí)候,點(diǎn)擊樹(shù)形圖,選擇release文件,將release文件中的所有文件添加進(jìn)來(lái)。其他部分按照教程或者默認(rèn)即可。最終會(huì)在項(xiàng)目目錄中生成Setup.exe文件。將Setup.exe安裝之后,就會(huì)在桌面生成快捷方式,點(diǎn)擊即可進(jìn)行游戲。
qt界面開(kāi)發(fā),C++,qt文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-783782.html

到了這里,關(guān)于【Qt設(shè)計(jì)開(kāi)發(fā)】GUI界面設(shè)計(jì)開(kāi)發(fā)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 軟件設(shè)計(jì)開(kāi)發(fā)筆記4:QT操作SQLite數(shù)據(jù)庫(kù)

    軟件設(shè)計(jì)開(kāi)發(fā)筆記4:QT操作SQLite數(shù)據(jù)庫(kù)

    ??有時(shí)候我們需要在軟件中記錄一些歷史數(shù)據(jù)以便于對(duì)數(shù)據(jù)的查詢。而我們希望軟件不能太復(fù)雜,體量也不要太大,這個(gè)時(shí)候就需要如SQLite這樣輕量級(jí)的數(shù)據(jù)庫(kù)。這篇中我們就來(lái)討論如何在使用QT開(kāi)發(fā)應(yīng)用是操作SQLite數(shù)據(jù)庫(kù)。 ??SQLite是一款開(kāi)源、輕量級(jí)、跨平臺(tái)的數(shù)據(jù)庫(kù)

    2024年02月09日
    瀏覽(24)
  • Qt音視頻開(kāi)發(fā)38-ffmpeg視頻暫停錄制的設(shè)計(jì)

    Qt音視頻開(kāi)發(fā)38-ffmpeg視頻暫停錄制的設(shè)計(jì)

    基本上各種播放器提供的錄制視頻接口,都是只有開(kāi)始錄制和結(jié)束錄制兩個(gè),當(dāng)然一般用的最多的也是這兩個(gè)接口,但是實(shí)際使用過(guò)程中,還有一種可能需要中途暫停錄制,暫停以后再次繼續(xù)錄制,將中間部分視頻不需要錄制,跳過(guò)這部分不需要的視頻,而且錄制的視頻文件

    2023年04月20日
    瀏覽(25)
  • Qt音視頻開(kāi)發(fā)45-音視頻類結(jié)構(gòu)體參數(shù)的設(shè)計(jì)

    Qt音視頻開(kāi)發(fā)45-音視頻類結(jié)構(gòu)體參數(shù)的設(shè)計(jì)

    視頻監(jiān)控內(nèi)核組件重構(gòu)和完善花了一年多時(shí)間,整個(gè)組件個(gè)人認(rèn)為設(shè)計(jì)的最好的部分就是各種結(jié)構(gòu)體參數(shù)的設(shè)計(jì),而且分門別類,有枚舉值,也有窗體相關(guān)的結(jié)構(gòu)體參數(shù),解碼相關(guān)的結(jié)構(gòu)體參數(shù),同時(shí)將部分常用的結(jié)構(gòu)體參數(shù)的獲取和設(shè)置單獨(dú)提供了函數(shù),參閱??荡笕A等大

    2024年02月05日
    瀏覽(30)
  • Qt音視頻開(kāi)發(fā)36-超時(shí)檢測(cè)和自動(dòng)重連的設(shè)計(jì)

    Qt音視頻開(kāi)發(fā)36-超時(shí)檢測(cè)和自動(dòng)重連的設(shè)計(jì)

    如果網(wǎng)絡(luò)環(huán)境正常設(shè)備正常,視頻監(jiān)控系統(tǒng)一般都是按照正常運(yùn)行下去,不會(huì)出現(xiàn)什么問(wèn)題,但是實(shí)際情況會(huì)很不同,奇奇怪怪七七八八的問(wèn)題都會(huì)出現(xiàn),就比如網(wǎng)絡(luò)出了問(wèn)題都有很多情況(交換機(jī)故障、網(wǎng)線故障、帶寬故障等),所以監(jiān)控系統(tǒng)在運(yùn)行過(guò)程中,還得做超時(shí)檢

    2023年04月13日
    瀏覽(31)
  • Qt開(kāi)發(fā)_調(diào)用OpenCV(3.4.7)設(shè)計(jì)完成人臉檢測(cè)系統(tǒng)

    Qt開(kāi)發(fā)_調(diào)用OpenCV(3.4.7)設(shè)計(jì)完成人臉檢測(cè)系統(tǒng)

    近年來(lái),人臉識(shí)別技術(shù)得到了廣泛的應(yīng)用,它可以在各種場(chǎng)景中實(shí)現(xiàn)自動(dòng)化的人臉檢測(cè)和識(shí)別,例如安防監(jiān)控、人臉解鎖、人臉支付等。 該項(xiàng)目的目標(biāo)是設(shè)計(jì)一個(gè)簡(jiǎn)單易用但功能強(qiáng)大的人臉檢測(cè)系統(tǒng),可以實(shí)時(shí)從攝像頭采集視頻,并對(duì)視頻中的人臉進(jìn)行準(zhǔn)確的檢測(cè)和框選。通

    2024年02月09日
    瀏覽(23)
  • QT軟件開(kāi)發(fā)-基于FFMPEG設(shè)計(jì)視頻播放器-軟解圖像(一)

    QT軟件開(kāi)發(fā)-基于FFMPEG設(shè)計(jì)視頻播放器-軟解圖像(一)

    QT軟件開(kāi)發(fā)-基于FFMPEG設(shè)計(jì)視頻播放器-CPU軟解視頻(一) https://xiaolong.blog.csdn.net/article/details/126832537 QT軟件開(kāi)發(fā)-基于FFMPEG設(shè)計(jì)視頻播放器-GPU硬解視頻(二) https://xiaolong.blog.csdn.net/article/details/126833434 QT軟件開(kāi)發(fā)-基于FFMPEG設(shè)計(jì)視頻播放器-解碼音頻(三) https://xiaolong.blog.csdn.

    2023年04月08日
    瀏覽(95)
  • 畢業(yè)設(shè)計(jì)項(xiàng)目——基于QT4+Opencv開(kāi)發(fā)的道路偏移檢測(cè)與預(yù)警系統(tǒng)

    完整項(xiàng)目地址:https://download.csdn.net/download/lijunhcn/88453342 基于QT4+Opencv的道路道路偏移檢測(cè)與預(yù)警系統(tǒng) 開(kāi)發(fā)環(huán)境:Ubuntu14.04+QT4.8.5+Opencv2.4.8 已經(jīng)實(shí)現(xiàn)的功能: 道路偏移檢測(cè) 道路偏移預(yù)警 串口讀取外部傳感器數(shù)據(jù) 部分源碼展示:

    2024年02月03日
    瀏覽(27)
  • 06-1_Qt 5.9 C++開(kāi)發(fā)指南_對(duì)話框與多窗體設(shè)計(jì)_標(biāo)準(zhǔn)對(duì)話框

    06-1_Qt 5.9 C++開(kāi)發(fā)指南_對(duì)話框與多窗體設(shè)計(jì)_標(biāo)準(zhǔn)對(duì)話框

    在一個(gè)完整的應(yīng)用程序設(shè)計(jì)中,不可避免地會(huì)涉及多個(gè)窗體、對(duì)話框的設(shè)計(jì)和調(diào)用,如何設(shè)計(jì)和調(diào)用這些對(duì)話框和窗體是搞清楚一個(gè)龐大的應(yīng)用程序設(shè)計(jì)的基礎(chǔ)。本章將介紹對(duì)話框和多窗體設(shè)計(jì)、調(diào)用方式、數(shù)據(jù)傳遞等問(wèn)題,主要包括以下幾點(diǎn)。 Qt 提供的標(biāo)準(zhǔn)對(duì)話框的使用,

    2024年02月13日
    瀏覽(103)
  • QT軟件開(kāi)發(fā)-基于FFMPEG設(shè)計(jì)錄屏與rtsp、rtmp推流軟件(支持桌面與攝像頭)(四)

    QT軟件開(kāi)發(fā)-基于FFMPEG設(shè)計(jì)錄屏與rtsp、rtmp推流軟件(支持桌面與攝像頭)(四)

    QT軟件開(kāi)發(fā)-基于FFMPEG設(shè)計(jì)錄屏與rtsp、rtmp推流軟件(支持桌面與攝像頭)(一) https://xiaolong.blog.csdn.net/article/details/126954626 QT軟件開(kāi)發(fā)-基于FFMPEG設(shè)計(jì)錄屏與rtsp、rtmp推流軟件(支持桌面與攝像頭)(二) https://xiaolong.blog.csdn.net/article/details/126958188 QT軟件開(kāi)發(fā)-基于FFMPEG設(shè)計(jì)錄屏與rt

    2023年04月19日
    瀏覽(26)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包