C/C++?QT實現(xiàn)自定義對話框的示例代碼
對話框分為多種,常見的有通用對話框,自定義對話框,模態(tài)對話框,非模態(tài)對話框等,其中通用對話框包括了,QFileDialog文件對話框,QColorDialog顏色對話框,QFontDialog字體對話框,QInputDialog輸入對話框等,自定義對話框則主要是實現(xiàn)自己布局的簡單頁面,區(qū)別于窗體對話框則顯得更加簡單一些,除對話框外,多窗體設(shè)計也是最常用的,例如多窗體嵌入,MID窗體等,下面則是每種窗體的代碼總結(jié)。
創(chuàng)建自定義窗體
1.首先使用兩個控件,TableView主要是表格處理,TreeView主要是樹形框,這兩者可以通過 QItemSelectionModel 模型綁定起來從而可實現(xiàn)菜單聯(lián)動。
# 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 << "序號" << "姓名" << "年齡" << "性別" << "婚否";
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(); // 獲取每個數(shù)組中元素數(shù)
int Array_Count = sizeof(DataList) / sizeof(DataList[0]); // 獲取數(shù)組個數(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;
}

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

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

4.設(shè)計好界面布局,然后開始寫代碼。

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(); // 獲取對話框輸入的行數(shù)
int columnCount(); // 獲取對話框輸入的列數(shù)
void etRowColumn(int row, int column); // 初始對話框上兩個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 主窗體中按鈕一被點擊時執(zhí)行。
// 當(dāng)按鈕1被點擊觸發(fā)
void MainWindow::on_pushButton_clicked()
{
DialogSize *ptr = new DialogSize(this); // 創(chuàng)建一個對話框
Qt::WindowFlags flags = ptr->windowFlags(); // 需要獲取返回值
ptr->setWindowFlags(flags | Qt::MSWindowsFixedSizeDialogHint); // 設(shè)置對話框固定大小
ptr->setRowColumn(model->rowCount(),model->columnCount()); // 對話框數(shù)據(jù)初始化
int ref = ptr->exec(); // 以模態(tài)方式顯示對話框
if (ref==QDialog::Accepted) // OK鍵被按下,對話框關(guān)閉
{
// 當(dāng)BtnOk被按下時,則設(shè)置對話框中的數(shù)據(jù)
int cols=ptr->columnCount();
model->setColumnCount(cols);
int rows=ptr->rowCount();
model->setRowCount(rows);
}
// 最后刪除釋放對話框句柄
delete ptr;
}
配置完后,我們還需要綁定兩個槽函數(shù),首先來到dialog窗體上,手動添加兩條槽函數(shù),當(dāng)按鈕被點擊后,后發(fā)送一個信號,主窗體接收到后處理即可。

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

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

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
// 對話框設(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)有的表頭標題
for (int i=0;i<model->columnCount();i++)
{
strList.append(model->headerData(i,Qt::Horizontal,Qt::DisplayRole).toString());
}
// 用于對話框初始化顯示
ptr->setHeaderList(strList);
}
int ref = ptr->exec(); // 調(diào)用彈窗
if(ref==QDialog::Accepted)
{
QStringList strList=ptr->headerList();//獲取對話框上修改后的StringList
model->setHorizontalHeaderLabels(strList);// 設(shè)置模型的表頭標題
}
delete ptr;
}
最后在Dialog上綁定信號與曹。

前面的交互都是使用傳統(tǒng)的相互引用實現(xiàn)的,實現(xiàn)起來較復(fù)雜,同樣可以使用信號與曹來實現(xiàn),將信號與曹關(guān)聯(lián)起來,在進行操作時發(fā)送信號,槽函數(shù)接受并相應(yīng)。
實現(xiàn)多窗體設(shè)計
多窗體分為窗體卡和MID窗體,這兩種窗體也最常用。
1.首先是窗體卡片,這里在創(chuàng)建是應(yīng)該選擇Widget窗體,這個窗體最干凈沒啥控件,所以我們選擇它。

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(); // 獲取選中標簽索引
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();//清除所有頁面
ui->tabWidget->tabsClosable(); //Page有關(guān)閉按鈕,可被關(guān)閉
}
MainWindow::~MainWindow()
{
delete ui;
}
// 定義函數(shù)來獲取當(dāng)前Table名字
QString MainWindow::GetTableNumber()
{
QString ref = QString(ui->tabWidget->currentIndex());
return ref;
}
void MainWindow::on_pushButton_clicked()
{
FormDoc *ptr = new FormDoc(this); // 新建選項卡
ptr->setAttribute(Qt::WA_DeleteOnClose); // 關(guān)閉時自動銷毀
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時執(zhí)行
void MainWindow::on_tabWidget_tabCloseRequested(int index)
{
if (index<0)
return;
QWidget* aForm=ui->tabWidget->widget(index);
aForm->close();
}
// 在無Tab頁面是默認禁用
void MainWindow::on_tabWidget_currentChanged(int index)
{
Q_UNUSED(index);
bool en=ui->tabWidget->count()>0;
ui->tabWidget->setVisible(en);
}

實現(xiàn)美觀對話框,前兩個對話框只能彈出一次,最后一個對話框可以彈出多次,主要代碼如下。
#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(); //清除所有頁面
ui->tabWidget->tabsClosable(); //Page有關(guān)閉按鈕,可被關(guān)閉
ui->tabWidget->setTabPosition(QTabWidget::North); // 設(shè)置選項卡方位
ui->tabWidget->setIconSize(QSize(50, 25)); // 設(shè)置圖標整體大小
//ui->tabWidget->setTabShape(QTabWidget::Triangular); // 設(shè)置選項卡形狀
ui->tabWidget->setMovable(true); // 設(shè)置選項卡是否可拖動
ui->tabWidget->usesScrollButtons(); // 選項卡滾動
ui->toolBar->setMovable(false);
}
MainWindow::~MainWindow()
{
delete ui;
}
// 首頁菜單創(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++)
{
// 獲取出每個菜單的標題
QString tab_name = ui->tabWidget->tabText(x);
if(tab_name == "首頁菜單")
option_count = option_count + 1;
}
if(option_count < 1)
{
FormMain *ptr = new FormMain(this); // 新建選項卡
ptr->setAttribute(Qt::WA_DeleteOnClose); // 關(guān)閉時自動銷毀
int cur=ui->tabWidget->addTab(ptr,QString::asprintf("首頁菜單"));
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++)
{
// 獲取出每個菜單的標題
QString tab_name = ui->tabWidget->tabText(x);
if(tab_name == "系統(tǒng)設(shè)置")
option_count = option_count + 1;
}
// 判斷首頁菜單是否只有一個,可判斷標簽個數(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);
}
}
// 繪圖頁面的彈出
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時
void MainWindow::on_tabWidget_tabCloseRequested(int index)
{
if (index<0)
return;
QWidget* aForm=ui->tabWidget->widget(index);
aForm->close();
}

到此這篇關(guān)于C/C++ QT實現(xiàn)自定義對話框的示例代碼的文章就介紹到這了,更多相關(guān)QT自定義對話框內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++中結(jié)構(gòu)體和Json字符串互轉(zhuǎn)的問題詳解
這篇文章主要給大家介紹了關(guān)于C++中結(jié)構(gòu)體和Json字符串互轉(zhuǎn)問題的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03
C++實現(xiàn)LeetCode(32.最長有效括號)
這篇文章主要介紹了C++實現(xiàn)LeetCode(32.最長有效括號),本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下2021-07-07
C++中strlen(),sizeof()與size()的區(qū)別
本文主要介紹了C++中strlen(),sizeof()與size()的區(qū)別,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-05-05

