溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

C/C++?QT實(shí)現(xiàn)自定義對(duì)話框的方法是什么

發(fā)布時(shí)間:2021-11-26 10:26:14 來(lái)源:億速云 閱讀:182 作者:iii 欄目:開(kāi)發(fā)技術(shù)

這篇文章主要講解了“C/C++ QT實(shí)現(xiàn)自定義對(duì)話框的方法是什么”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來(lái)研究和學(xué)習(xí)“C/C++ QT實(shí)現(xiàn)自定義對(duì)話框的方法是什么”吧!

對(duì)話框分為多種,常見(jiàn)的有通用對(duì)話框,自定義對(duì)話框,模態(tài)對(duì)話框,非模態(tài)對(duì)話框等,其中通用對(duì)話框包括了,QFileDialog文件對(duì)話框,QColorDialog顏色對(duì)話框,QFontDialog字體對(duì)話框,QInputDialog輸入對(duì)話框等,自定義對(duì)話框則主要是實(shí)現(xiàn)自己布局的簡(jiǎn)單頁(yè)面,區(qū)別于窗體對(duì)話框則顯得更加簡(jiǎn)單一些,除對(duì)話框外,多窗體設(shè)計(jì)也是最常用的,例如多窗體嵌入,MID窗體等,下面則是每種窗體的代碼總結(jié)。

創(chuàng)建自定義窗體

1.首先使用兩個(gè)控件,TableView主要是表格處理,TreeView主要是樹(shù)形框,這兩者可以通過(guò) QItemSelectionModel 模型綁定起來(lái)從而可實(shí)現(xiàn)菜單聯(lián)動(dòng)。

# mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <iostream>
#include <QStandardItem>
#include <QItemSelectionModel>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

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

private:
    Ui::MainWindow *ui;
    QStandardItemModel *model;       // 定義數(shù)據(jù)模型
    QItemSelectionModel *selection;  // 定義Item選擇模型
};
#endif // MAINWINDOW_H
# mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

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

    model = new QStandardItemModel(4,5,this);
    selection = new QItemSelectionModel(model);

    // 關(guān)聯(lián)到tableView
    ui->tableView->setModel(model);
    ui->tableView->setSelectionModel(selection);

    // 關(guān)聯(lián)到treeView
    ui->treeView->setModel(model);
    ui->treeView->setSelectionModel(selection);

    // 添加表頭
    QStringList HeaderList;
    HeaderList << "序號(hào)" << "姓名" << "年齡" << "性別" << "婚否";
    model->setHorizontalHeaderLabels(HeaderList);

    // 批量添加數(shù)據(jù)
    QStringList DataList[3];
    QStandardItem *Item;

    DataList[0] << "1001" << "admin" << "24" << "男" << "是";
    DataList[1] << "1002" << "lyshark" << "23" << "男" << "否";
    DataList[2] << "1003" << "lucy" << "37" << "女" << "是";

    int Array_Length = DataList->length();                          // 獲取每個(gè)數(shù)組中元素?cái)?shù)
    int Array_Count = sizeof(DataList) / sizeof(DataList[0]);       // 獲取數(shù)組個(gè)數(shù)

    for(int x=0; x<Array_Count; x++)
    {
        for(int y=0; y<Array_Length; y++)
        {
            Item = new QStandardItem(DataList[x][y]);
            model->setItem(x,y,Item);
        }
    }
}

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

C/C++?QT實(shí)現(xiàn)自定義對(duì)話框的方法是什么

2.首先來(lái)創(chuàng)建一個(gè)自定義對(duì)話框,創(chuàng)建對(duì)話框先要在項(xiàng)目上右鍵,選項(xiàng)【addNew】選擇【QT】點(diǎn)擊【QT設(shè)計(jì)師】,我們這里選擇最后一個(gè)最為界面框架。

C/C++?QT實(shí)現(xiàn)自定義對(duì)話框的方法是什么

3.默認(rèn)情況下,QT會(huì)生成三個(gè)文件【.ui 界面庫(kù)】【.h 頭文件】【.cpp 源文件】名字相同的三個(gè)文件,對(duì)應(yīng)一個(gè)界面。

C/C++?QT實(shí)現(xiàn)自定義對(duì)話框的方法是什么

4.設(shè)計(jì)好界面布局,然后開(kāi)始寫(xiě)代碼。

C/C++?QT實(shí)現(xiàn)自定義對(duì)話框的方法是什么

dialogsize.h

#ifndef DIALOGSIZE_H
#define DIALOGSIZE_H

#include <QDialog>

namespace Ui {
class DialogSize;
}

class DialogSize : public QDialog
{
    Q_OBJECT

public:
    explicit DialogSize(QWidget *parent = nullptr);
    ~DialogSize();

    int rowCount();                         // 獲取對(duì)話框輸入的行數(shù)
    int columnCount();                      // 獲取對(duì)話框輸入的列數(shù)
    void etRowColumn(int row, int column);  // 初始對(duì)話框上兩個(gè)SpinBox的值

private:
    Ui::DialogSize *ui;
};

#endif // DIALOGSIZE_H

dialogsize.cpp

#include "dialogsize.h"
#include "ui_dialogsize.h"

DialogSize::DialogSize(QWidget *parent) :QDialog(parent),ui(new Ui::DialogSize)
{
    ui->setupUi(this);
}

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

// 主窗體調(diào)用獲取當(dāng)前行數(shù)
int DialogSize::rowCount()
{
    return  ui->spinBoxRow->value();
}

// 主窗體調(diào)用獲取當(dāng)前列數(shù)
int DialogSize::columnCount()
{
    return  ui->spinBoxColumn->value();
}

// 設(shè)置主窗體中的TableView行數(shù)與列數(shù)
void DialogSize::setRowColumn(int row, int column)
{
    ui->spinBoxRow->setValue(row);
    ui->spinBoxColumn->setValue(column);
}

mainwindow.cpp 主窗體中按鈕一被點(diǎn)擊時(shí)執(zhí)行。

// 當(dāng)按鈕1被點(diǎn)擊觸發(fā)
void MainWindow::on_pushButton_clicked()
{
    DialogSize *ptr = new DialogSize(this);     // 創(chuàng)建一個(gè)對(duì)話框
    Qt::WindowFlags flags = ptr->windowFlags(); // 需要獲取返回值
    ptr->setWindowFlags(flags | Qt::MSWindowsFixedSizeDialogHint);  // 設(shè)置對(duì)話框固定大小
    ptr->setRowColumn(model->rowCount(),model->columnCount());      // 對(duì)話框數(shù)據(jù)初始化

    int ref = ptr->exec();             // 以模態(tài)方式顯示對(duì)話框
    if (ref==QDialog::Accepted)        // OK鍵被按下,對(duì)話框關(guān)閉
    {
        // 當(dāng)BtnOk被按下時(shí),則設(shè)置對(duì)話框中的數(shù)據(jù)
        int cols=ptr->columnCount();
        model->setColumnCount(cols);

        int rows=ptr->rowCount();
        model->setRowCount(rows);
    }
    
    // 最后刪除釋放對(duì)話框句柄
    delete ptr;
}

配置完后,我們還需要綁定兩個(gè)槽函數(shù),首先來(lái)到dialog窗體上,手動(dòng)添加兩條槽函數(shù),當(dāng)按鈕被點(diǎn)擊后,后發(fā)送一個(gè)信號(hào),主窗體接收到后處理即可。

C/C++?QT實(shí)現(xiàn)自定義對(duì)話框的方法是什么

運(yùn)行效果如下,這是一個(gè)模態(tài)對(duì)話框,所謂模態(tài)就是說(shuō),當(dāng)打開(kāi)時(shí)不能再次操作主窗體,只有模態(tài)對(duì)話框關(guān)閉時(shí)才能繼續(xù)操作主窗體。

C/C++?QT實(shí)現(xiàn)自定義對(duì)話框的方法是什么

接著來(lái)寫(xiě)一個(gè)非模態(tài)對(duì)話框,這次創(chuàng)建一個(gè)Dialog名字就叫做DialogHead并繪制好界面。

C/C++?QT實(shí)現(xiàn)自定義對(duì)話框的方法是什么

dialoghead.h

#ifndef DIALOGHEAD_H
#define DIALOGHEAD_H

#include <QDialog>
#include <QStringListModel>

namespace Ui {
class DialogHead;
}

class DialogHead : public QDialog
{
    Q_OBJECT

public:
    explicit DialogHead(QWidget *parent = nullptr);
    ~DialogHead();

    void setHeaderList(QStringList& headers);   // 設(shè)置表頭數(shù)據(jù)
    QStringList headerList();                   // 返回表頭數(shù)據(jù)
private:
    QStringListModel *model;       // 定義數(shù)據(jù)模型
    Ui::DialogHead *ui;
};

#endif // DIALOGHEAD_H

dialoghead.cpp

#include "dialoghead.h"
#include "ui_dialoghead.h"

DialogHead::DialogHead(QWidget *parent) :QDialog(parent),ui(new Ui::DialogHead)
{
    ui->setupUi(this);
    model = new QStringListModel;
    ui->listView->setModel(model);
}

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

// 設(shè)置當(dāng)前l(fā)istView中的數(shù)據(jù)
void DialogHead::setHeaderList(QStringList &headers)
{
    model->setStringList(headers);
}
// 返回當(dāng)前的表頭
QStringList DialogHead::headerList()
{
    return model->stringList();
}

mainwindow.cpp

// 對(duì)話框設(shè)置表頭數(shù)據(jù)
void MainWindow::on_pushButton_2_clicked()
{
    DialogHead *ptr = new DialogHead(this);
    Qt::WindowFlags flags = ptr->windowFlags();
    ptr->setWindowFlags(flags | Qt::MSWindowsFixedSizeDialogHint);

    // 如果表頭列數(shù)變化,則從新初始化
    if(ptr->headerList().count() != model->columnCount())
    {
        QStringList strList;

        // 獲取現(xiàn)有的表頭標(biāo)題
        for (int i=0;i<model->columnCount();i++)
        {
            strList.append(model->headerData(i,Qt::Horizontal,Qt::DisplayRole).toString());
        }

        // 用于對(duì)話框初始化顯示
        ptr->setHeaderList(strList);
    }

    int ref = ptr->exec();  // 調(diào)用彈窗
    if(ref==QDialog::Accepted)
    {
        QStringList strList=ptr->headerList();//獲取對(duì)話框上修改后的StringList
        model->setHorizontalHeaderLabels(strList);// 設(shè)置模型的表頭標(biāo)題
    }

    delete ptr;
}

最后在Dialog上綁定信號(hào)與曹。

C/C++?QT實(shí)現(xiàn)自定義對(duì)話框的方法是什么

前面的交互都是使用傳統(tǒng)的相互引用實(shí)現(xiàn)的,實(shí)現(xiàn)起來(lái)較復(fù)雜,同樣可以使用信號(hào)與曹來(lái)實(shí)現(xiàn),將信號(hào)與曹關(guān)聯(lián)起來(lái),在進(jìn)行操作時(shí)發(fā)送信號(hào),槽函數(shù)接受并相應(yīng)。

實(shí)現(xiàn)多窗體設(shè)計(jì)

多窗體分為窗體卡和MID窗體,這兩種窗體也最常用。

1.首先是窗體卡片,這里在創(chuàng)建是應(yīng)該選擇Widget窗體,這個(gè)窗體最干凈沒(méi)啥控件,所以我們選擇它。

C/C++?QT實(shí)現(xiàn)自定義對(duì)話框的方法是什么

formdoc.h

#ifndef FORMDOC_H
#define FORMDOC_H

#include <QWidget>

namespace Ui {
class FormDoc;
}

class FormDoc : public QWidget
{
    Q_OBJECT

public:
    explicit FormDoc(QWidget *parent = nullptr);
    ~FormDoc();

private:
    Ui::FormDoc *ui;
};

#endif // FORMDOC_H

formdoc.cpp

#include "formdoc.h"
#include "ui_formdoc.h"
#include "mainwindow.h"

#include <QVBoxLayout>
#include <iostream>

FormDoc::FormDoc(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::FormDoc)
{
    ui->setupUi(this);

    QVBoxLayout *Layout = new QVBoxLayout();
    Layout->setContentsMargins(2,2,2,2);
    Layout->setSpacing(2);
    this->setLayout(Layout);

    MainWindow *parWind = (MainWindow*)parentWidget(); //獲取父窗口指針
    QString ref = parWind->GetTableNumber();           // 獲取選中標(biāo)簽索引
    std::cout << ref.toStdString().data() << std::endl;
}

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

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

#include "formdoc.h"

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
    QString GetTableNumber();

private slots:
    void on_pushButton_clicked();

    void on_tabWidget_tabCloseRequested(int index);

    void on_tabWidget_currentChanged(int index);

private:
    Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <iostream>

MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    ui->tabWidget->setVisible(false);
    ui->tabWidget->clear();//清除所有頁(yè)面
    ui->tabWidget->tabsClosable(); //Page有關(guān)閉按鈕,可被關(guān)閉
}

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

// 定義函數(shù)來(lái)獲取當(dāng)前Table名字
QString MainWindow::GetTableNumber()
{
    QString ref = QString(ui->tabWidget->currentIndex());
    return ref;
}

void MainWindow::on_pushButton_clicked()
{
    FormDoc *ptr = new FormDoc(this);                // 新建選項(xiàng)卡
    ptr->setAttribute(Qt::WA_DeleteOnClose);         // 關(guān)閉時(shí)自動(dòng)銷(xiāo)毀

    int cur = ui->tabWidget->addTab(ptr,QString::asprintf(" 192.168.1.%d",ui->tabWidget->count()));

    ui->tabWidget->setTabIcon(cur,QIcon(":/image/1.ico"));

    ui->tabWidget->setCurrentIndex(cur);
    ui->tabWidget->setVisible(true);
}

// 關(guān)閉Tab時(shí)執(zhí)行
void MainWindow::on_tabWidget_tabCloseRequested(int index)
{
    if (index<0)
        return;
    QWidget* aForm=ui->tabWidget->widget(index);
    aForm->close();
}

// 在無(wú)Tab頁(yè)面是默認(rèn)禁用
void MainWindow::on_tabWidget_currentChanged(int index)
{
    Q_UNUSED(index);
    bool en=ui->tabWidget->count()>0;
    ui->tabWidget->setVisible(en);
}

C/C++?QT實(shí)現(xiàn)自定義對(duì)話框的方法是什么

實(shí)現(xiàn)美觀對(duì)話框,前兩個(gè)對(duì)話框只能彈出一次,最后一個(gè)對(duì)話框可以彈出多次,主要代碼如下。

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <iostream>

#include "formmain.h"
#include "formoption.h"
#include "formcharts.h"

MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    ui->tabWidget->setVisible(false);
    ui->tabWidget->clear();        //清除所有頁(yè)面
    ui->tabWidget->tabsClosable(); //Page有關(guān)閉按鈕,可被關(guān)閉

    ui->tabWidget->setTabPosition(QTabWidget::North);       // 設(shè)置選項(xiàng)卡方位
    ui->tabWidget->setIconSize(QSize(50, 25));              // 設(shè)置圖標(biāo)整體大小
    //ui->tabWidget->setTabShape(QTabWidget::Triangular);   // 設(shè)置選項(xiàng)卡形狀
    ui->tabWidget->setMovable(true);                        // 設(shè)置選項(xiàng)卡是否可拖動(dòng)
    ui->tabWidget->usesScrollButtons();                     // 選項(xiàng)卡滾動(dòng)

    ui->toolBar->setMovable(false);
}

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

// 首頁(yè)菜單創(chuàng)建
void MainWindow::on_actionMain_triggered()
{
    int tab_count = ui->tabWidget->count();
    int option_count = 0;

    for(int x=0; x < tab_count; x++)
    {
        // 獲取出每個(gè)菜單的標(biāo)題
        QString tab_name = ui->tabWidget->tabText(x);

        if(tab_name == "首頁(yè)菜單")
            option_count = option_count + 1;
    }

    if(option_count < 1)
    {
        FormMain *ptr = new FormMain(this);              // 新建選項(xiàng)卡
        ptr->setAttribute(Qt::WA_DeleteOnClose);         // 關(guān)閉時(shí)自動(dòng)銷(xiāo)毀

        int cur=ui->tabWidget->addTab(ptr,QString::asprintf("首頁(yè)菜單"));
        ui->tabWidget->setTabIcon(cur,QIcon(":/image/1.ico"));

        ui->tabWidget->setCurrentIndex(cur);
        ui->tabWidget->setVisible(true);
    }
}

// 創(chuàng)建系統(tǒng)設(shè)置菜單
void MainWindow::on_actionOption_triggered()
{
    int tab_count = ui->tabWidget->count();
    int option_count = 0;

    for(int x=0; x < tab_count; x++)
    {
        // 獲取出每個(gè)菜單的標(biāo)題
        QString tab_name = ui->tabWidget->tabText(x);

        if(tab_name == "系統(tǒng)設(shè)置")
            option_count = option_count + 1;
    }

    // 判斷首頁(yè)菜單是否只有一個(gè),可判斷標(biāo)簽個(gè)數(shù)來(lái)識(shí)別
    if(option_count < 1)
    {
        FormOption *ptr = new FormOption(this);
        ptr->setAttribute(Qt::WA_DeleteOnClose);

        int cur = ui->tabWidget->addTab(ptr,QString::asprintf("系統(tǒng)設(shè)置"));
        ui->tabWidget->setTabIcon(cur,QIcon(":/image/2.ico"));

        ui->tabWidget->setCurrentIndex(cur);
        ui->tabWidget->setVisible(true);
    }
}

// 繪圖頁(yè)面的彈出
void MainWindow::on_actionCharts_triggered()
{
    FormCharts *ptr = new FormCharts(this);

    ptr->setAttribute(Qt::WA_DeleteOnClose);

    int cur = ui->tabWidget->addTab(ptr,QString::asprintf("圖形繪制"));
    ui->tabWidget->setTabIcon(cur,QIcon(":/image/3.ico"));

    ui->tabWidget->setCurrentIndex(cur);
    ui->tabWidget->setVisible(true);
}

// 關(guān)閉TabWiget時(shí)
void MainWindow::on_tabWidget_tabCloseRequested(int index)
{
    if (index<0)
        return;
    QWidget* aForm=ui->tabWidget->widget(index);
    aForm->close();
}

C/C++?QT實(shí)現(xiàn)自定義對(duì)話框的方法是什么

感謝各位的閱讀,以上就是“C/C++ QT實(shí)現(xiàn)自定義對(duì)話框的方法是什么”的內(nèi)容了,經(jīng)過(guò)本文的學(xué)習(xí)后,相信大家對(duì)C/C++ QT實(shí)現(xiàn)自定義對(duì)話框的方法是什么這一問(wèn)題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI