日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Qt中的QDialog

發布時間:2025/4/5 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Qt中的QDialog 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

    • 1 Qt中的QDialog
      • 1.1 QDialog簡介
      • 1.2 模態對話框和非模態對話框
      • 1.3 對話框的返回值
    • 2 登陸對話框實例分析
      • 2.1 分析
      • 2.2 代碼實現
      • 2.3 登錄對話框的改進
    • 3 Qt種的標準對話框

1 Qt中的QDialog

1.1 QDialog簡介

對話框的概念:

  • 對話框是與用戶進行簡短交互的頂層窗口。
  • QDialog是Qt中所有對話框窗口的基類。
  • QDialog繼承于QWidget是一種容器類型的組件。

    QDialog的意義:
  • QDialog作為一種專用的交互窗口而存在。
  • QDialog不能作為子部件嵌入其它容器中。
  • QDialog是定制了窗口樣式的特殊的QWidget。

注意:如果QDialog沒有指定parent是不會一直處于最上層的,如果制定了parent則會一直處于最上層。

1.2 模態對話框和非模態對話框

模態對話框(QDialog::exec()):

  • 顯示后無法與父窗口進行交互。
  • 是一種阻塞式的對話框調用方式。

非模態對話框(QDialog::show()):

  • 顯示后獨立存在可以同時與父窗口進行交互。
  • 是一種非阻塞式的對話框調用方式。

一般情況下:

  • 模態對話框用于必須依賴用戶選擇的場合(80%):
    • 消息提示、文件選擇、打印設置等。
  • 非模態對話框用于特殊功能設置的場合(20%):
    • 查找操作、屬性設置等。

小技巧:

  • 在棧上創建模態對話框是最簡單常用的方式。
  • 一般情況下非模態對話框需要在堆上創建。
  • 通過QDialog::setModal函數可以創建混合特性的對話框(不會阻塞,但是必須做出選擇)。
  • 非模態對話框需要指定Qt::WA_DeleteOnClose屬性。

測試代碼如下:

Dialog.h:

#ifndef DIALOG_H #define DIALOG_H#include <QtGui/QDialog> #include <QPushButton>class Dialog : public QDialog {Q_OBJECT protected:QPushButton ModalBtn;QPushButton NormalBtn;QPushButton MixedBtn; protected slots:void ModalBtn_Clicked();void NormalBtn_Clicked();void MixedBtn_Clicked(); public:Dialog(QWidget *parent = 0);~Dialog(); };#endif // DIALOG_H

Dialog.cpp:

#include "Dialog.h"#include <QDebug>Dialog::Dialog(QWidget *parent) :QDialog(parent), ModalBtn(this), NormalBtn(this), MixedBtn(this) {ModalBtn.setText("Modal Dialog");ModalBtn.move(20, 20);ModalBtn.resize(100, 30);NormalBtn.setText("Normal Dialog");NormalBtn.move(20, 70);NormalBtn.resize(100, 30);MixedBtn.setText("Mixed Dialog");MixedBtn.move(20, 120);MixedBtn.resize(100, 30);connect(&ModalBtn, SIGNAL(clicked()), this, SLOT(ModalBtn_Clicked()));connect(&NormalBtn, SIGNAL(clicked()), this, SLOT(NormalBtn_Clicked()));connect(&MixedBtn, SIGNAL(clicked()), this, SLOT(MixedBtn_Clicked()));resize(140, 170); }void Dialog::ModalBtn_Clicked() {qDebug() << "ModalBtn_Clicked() Begin";QDialog dialog(this);dialog.exec();qDebug() << "ModalBtn_Clicked() End"; }void Dialog::NormalBtn_Clicked() {qDebug() << "NormalBtn_Clicked() Begin";QDialog* dialog = new QDialog(this);dialog->setAttribute(Qt::WA_DeleteOnClose);dialog->show();qDebug() << "NormalBtn_Clicked() End"; }void Dialog::MixedBtn_Clicked() {qDebug() << "MixedBtn_Clicked() Begin";QDialog* dialog = new QDialog(this);dialog->setAttribute(Qt::WA_DeleteOnClose);dialog->setModal(true);dialog->show();qDebug() << "MixedBtn_Clicked() End"; }Dialog::~Dialog() {qDebug() << "~Dialog()"; }

main.cpp:

#include <QtGui/QApplication> #include <QWidget> #include <QDialog> #include <QDebug> #include "Dialog.h"int main(int argc, char *argv[]) {QApplication a(argc, argv);Dialog dlg;dlg.show();return a.exec(); }

1.3 對話框的返回值

只有模態對話框才有返回值的概念:

  • 模態對話框的返回值用于表示交互結果。
  • QDialog::exec()的返回值為交互結果:
    • void QDialog::done(int i)關閉對話框并將參數作為交互結果。
    • QDialog::Accepted:用戶操作成功。
    • QDialog:Rejected:用戶操作失敗。

測試代碼如下:
QDialog.h的代碼和上面一樣,就不貼了。

QDialog.cpp:

#include "Dialog.h"#include <QDebug>Dialog::Dialog(QWidget *parent) :QDialog(parent), ModalBtn(this), NormalBtn(this), MixedBtn(this) {ModalBtn.setText("Modal Dialog");ModalBtn.move(20, 20);ModalBtn.resize(100, 30);NormalBtn.setText("Normal Dialog");NormalBtn.move(20, 70);NormalBtn.resize(100, 30);MixedBtn.setText("Mixed Dialog");MixedBtn.move(20, 120);MixedBtn.resize(100, 30);connect(&ModalBtn, SIGNAL(clicked()), this, SLOT(ModalBtn_Clicked()));connect(&NormalBtn, SIGNAL(clicked()), this, SLOT(NormalBtn_Clicked()));connect(&MixedBtn, SIGNAL(clicked()), this, SLOT(MixedBtn_Clicked()));resize(140, 170); }void Dialog::ModalBtn_Clicked() {done(Accepted); }void Dialog::NormalBtn_Clicked() {done(Rejected); }void Dialog::MixedBtn_Clicked() {done(100); }Dialog::~Dialog() {qDebug() << "~Dialog()"; }

main.cpp:

#include <QtGui/QApplication> #include <QWidget> #include <QDialog> #include <QDebug> #include "Dialog.h"int main(int argc, char *argv[]) {QApplication a(argc, argv);Dialog dlg;int r = dlg.exec();if( r == QDialog::Accepted ){qDebug() << "Accepted";}else if( r == QDialog::Rejected ){qDebug() << "Rejected";}else{qDebug() << r;}return r; }

2 登陸對話框實例分析

2.1 分析

登陸對話框是應用程序中的常用部件,思考:如何開發一個可以在不同項目間復用的登陸對話框?

登陸對話框需求分析:

  • 可復用軟件部分。
  • 獲取用戶名和密碼。

附加需求:

  • 隨機驗證碼。

登陸對話框的設計與架構:

如何獲取用戶輸入的用戶名和密碼:

  • 如何在兩個不同的對話框之間傳遞數據?


對話框之間通過成員變量和成員函數傳遞數據:

  • 將用戶數據保存在私有成員變量中。
  • 通過公有成員函數進行數據傳遞。

我們話可以進一步開發(這里未完成):

  • 檢查用戶名和密碼是否為空:
    • 當用戶名或密碼為空時提示錯誤。
  • 隨機驗證碼:
    • 當驗證碼輸入錯誤時進行提示。
    • 驗證碼隨機刷新。

2.2 代碼實現

代碼組織如下:

QLoginDialog.h:

#ifndef _QLOGINDIALOG_H_ #define _QLOGINDIALOG_H_#include <QtGui/QDialog> #include <QLabel> #include <QLineEdit> #include <QPushButton>class QLoginDialog : public QDialog {Q_OBJECT private:QLabel UserLabel;QLabel PwdLabel;QLineEdit UserEdit;QLineEdit PwdEdit;QPushButton LoginBtn;QPushButton CancelBtn;QString m_user;QString m_pwd; private slots:void LoginBtn_Clicked();void CancelBtn_Clicked(); public:QLoginDialog(QWidget *parent = 0);QString getUser();QString getPwd();~QLoginDialog(); };#endif

QLoginDialog.cpp:

#include "QLoginDialog.h"QLoginDialog::QLoginDialog(QWidget *parent): QDialog(parent, Qt::WindowCloseButtonHint), m_lblName(this), m_lblPwd(this), m_editName(this), m_editPwd(this),m_btnCancle(this), m_btnLogin(this) {setWindowTitle("Login");setFixedSize(285, 170);m_lblName.setText("User ID:");m_lblName.resize(80, 25);m_lblName.move(10, 30);m_lblPwd.setText("Password:");m_lblPwd.resize(80, 25);m_lblPwd.move(10, 65);m_editName.move(95, 30);m_editName.resize(180, 25);m_editPwd.move(95, 65);m_editPwd.resize(180, 25);m_editPwd.setEchoMode(QLineEdit::Password);m_btnCancle.setText("Cancle");m_btnCancle.resize(85, 30);m_btnCancle.move(95, 110);m_btnLogin.setText("Login");m_btnLogin.resize(85, 30);m_btnLogin.move(190, 110);connect(&m_btnCancle, SIGNAL(clicked()), this, SLOT(onBtnCancleClicked()));connect(&m_btnLogin, SIGNAL(clicked()), this, SLOT(onBtnLoginClicked())); }void QLoginDialog::onBtnCancleClicked() {m_name = "";m_pwd = "";done(Rejected); }void QLoginDialog::onBtnLoginClicked() {m_name = m_editName.text().trimmed();m_pwd = m_editPwd.text();done(Accepted); }QString QLoginDialog::getName() {return m_name; }QString QLoginDialog::getPwd() {return m_pwd; }QLoginDialog::~QLoginDialog() {}

Widget.h:

#ifndef _WIDGET_H_ #define _WIDGET_H_#include <QtGui/QWidget> #include <QPushButton>class Widget : public QWidget {Q_OBJECT private:QPushButton TestBtn; private slots:void TestBtn_Clicked(); public:Widget(QWidget *parent = 0);~Widget(); };#endif

Widget.cpp:

#include "Widget.h" #include "QLoginDialog.h" #include "QDebug"Widget::Widget(QWidget *parent) :QWidget(parent), m_btnTestLoginDialog(this) {m_btnTestLoginDialog.setText("Test login dialog");setFixedSize(300, 200);connect(&m_btnTestLoginDialog, SIGNAL(clicked()), this, SLOT(onBtnTest())); }void Widget::onBtnTest() {QLoginDialog loginDlg(this);if (loginDlg.exec() == QDialog::Accepted){qDebug() << loginDlg.getName();qDebug() << loginDlg.getPwd();} }

main.cpp:

#include <QtGui/QApplication> #include "QLoginDialog.h" #include "Widget.h"int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); }

2.3 登錄對話框的改進

分析下如上對話框存在的問題:

  • 沒有實現驗證碼功能,容易被惡意程序攻擊,盜取用戶名和密碼。

改進思路-驗證碼機制:

  • 隨機產生驗證碼。
  • 用戶后填寫。
  • 判斷用戶識別的正確性。
  • 需求:

    • 驗證碼必須能夠有效避開惡意程序的識別!

    關于驗證碼和惡意程序:

    • 自動測試原理:
      • 利用一些特殊的系統函數能夠通過代碼控制程序,從而模擬用戶操作。
    • 惡意程序:
      • 使用自動測試原理對目標程序進行控制,從而盜取信息或進行攻擊。
    • 驗證碼:
      • 隨機產生,用戶容易識別,程序難以識別,從而有效避免惡意攻擊。

    需要注意的問題:

    • 驗證碼必須動態隨機產生。
    • 驗證碼的顯示避開使用標準組件(標簽、文本框等)。
    • 驗證碼應該附帶足夠多的障礙增加程序識別難度。

    解決方案:

  • 隨機產生目標驗證碼。
  • 將驗證碼直接繪制于登錄對話框。
  • 驗證碼中的字符顏色隨機改變。
  • 在驗證碼區域隨機繪制噪點。
  • 關于隨機數:

    • 計算機無法產生真正意義上的隨機數。
    • 計算機只能模擬隨機數序列(偽隨機數)。
    • 隨機種子決定每次產生的隨機序列是否相同。


    隨機產生驗證碼:

    驗證碼繪制:

    改進后的代碼如下:

    QLoginDialog.h:

    #ifndef _QLOGINDIALOG_H_ #define _QLOGINDIALOG_H_#include <QtGui/QDialog> #include <QLabel> #include <QLineEdit> #include <QPushButton> #include <QTimer>class QLoginDialog : public QDialog {Q_OBJECT private:QLabel UserLabel;QLabel PwdLabel;QLabel CaptLabel;QLineEdit UserEdit;QLineEdit PwdEdit;QLineEdit CaptEdit;QPushButton LoginBtn;QPushButton CancelBtn;QString m_user;QString m_pwd;QString m_captcha;Qt::GlobalColor* m_colors;QTimer m_timer; private slots:void LoginBtn_Clicked();void CancelBtn_Clicked();void Timer_Timeout(); protected:void paintEvent(QPaintEvent *);QString getCaptcha();Qt::GlobalColor* getColors(); public:QLoginDialog(QWidget *parent = 0);QString getUser();QString getPwd();~QLoginDialog(); };#endif

    QLoginDialog.cpp:

    #include "QLoginDialog.h" #include <QPainter> #include <QTime> #include <QDebug> #include <QMessageBox>QLoginDialog::QLoginDialog(QWidget* parent) : QDialog(parent, Qt::WindowCloseButtonHint),UserLabel(this), PwdLabel(this), CaptLabel(this),UserEdit(this), PwdEdit(this), CaptEdit(this),LoginBtn(this), CancelBtn(this) {UserLabel.setText("User ID:");UserLabel.move(20, 30);UserLabel.resize(60, 25);UserEdit.move(85, 30);UserEdit.resize(180, 25);PwdLabel.setText("Password:");PwdLabel.move(20, 65);PwdLabel.resize(60,25);PwdEdit.move(85, 65);PwdEdit.resize(180, 25);PwdEdit.setEchoMode(QLineEdit::Password);CaptLabel.setText("Captcha:");CaptLabel.move(20, 100);CaptLabel.resize(60, 25);CaptEdit.move(85, 100);CaptEdit.resize(85, 25);CancelBtn.setText("Cancel");CancelBtn.move(85, 145);CancelBtn.resize(85, 30);LoginBtn.setText("Login");LoginBtn.move(180, 145);LoginBtn.resize(85, 30);m_timer.setParent(this);setWindowTitle("Login");setFixedSize(285, 205);connect(&m_timer, SIGNAL(timeout()), this, SLOT(Timer_Timeout()));connect(&LoginBtn, SIGNAL(clicked()), this, SLOT(LoginBtn_Clicked()));connect(&CancelBtn, SIGNAL(clicked()), this, SLOT(CancelBtn_Clicked()));qsrand(QTime::currentTime().second() * 1000 + QTime::currentTime().msec());m_captcha = getCaptcha();m_colors = getColors();m_timer.start(100); }void QLoginDialog::LoginBtn_Clicked() {qDebug() << "LoginBtn_Clicked() Begin";QString captcha = CaptEdit.text().replace(" ", "");if( m_captcha.toLower() == captcha.toLower() ){m_user = UserEdit.text().trimmed();m_pwd = PwdEdit.text();if( m_user == "" ){QMessageBox::information(this, "Info", "User ID can NOT be empty!");}else if( m_pwd == "" ){QMessageBox::information(this, "Info", "Password can NOT be empty!");}else{done(Accepted);}}else{QMessageBox::critical(this, "Error", "The captcha is NOT matched!");m_captcha = getCaptcha();CaptEdit.selectAll();}qDebug() << "LoginBtn_Clicked() End"; }void QLoginDialog::CancelBtn_Clicked() {qDebug() << "CancelBtn_Clicked() Begin";done(Rejected);qDebug() << "CancelBtn_Clicked() End"; }QString QLoginDialog::getUser() {return m_user; }QString QLoginDialog::getPwd() {return m_pwd; }void QLoginDialog::Timer_Timeout() {m_colors = getColors();update(); }void QLoginDialog::paintEvent(QPaintEvent *) {QPainter painter(this);painter.fillRect(180, 100, 84, 24, Qt::white);painter.setFont(QFont("Comic Sans MS", 12));for(int i=0; i<150; i++){painter.setPen(m_colors[i%4]);painter.drawPoint(180 + qrand() % 84, 100 + qrand() % 24);}for(int i=0; i<4; i++){painter.setPen(m_colors[i]);painter.drawText(180 + 20 * i, 100, 20, 24, Qt::AlignCenter, QString(m_captcha[i]));} }QString QLoginDialog::getCaptcha() {QString ret = "";for(int i=0; i<4; i++){int c = (qrand() % 2) ? 'a' : 'A';ret += static_cast<QChar>(c + qrand() % 26);}return ret; }Qt::GlobalColor* QLoginDialog::getColors() {static Qt::GlobalColor colors[4];for(int i=0; i<4; i++){colors[i] = static_cast<Qt::GlobalColor>(2 + qrand() % 16);}return colors; }QLoginDialog::~QLoginDialog() {}

    Widget.h:

    #ifndef _WIDGET_H_ #define _WIDGET_H_#include <QtGui/QWidget> #include <QPushButton>class Widget : public QWidget {Q_OBJECT private:QPushButton TestBtn; private slots:void TestBtn_Clicked(); public:Widget(QWidget *parent = 0);~Widget(); };#endif

    Widget.cpp:

    #include "Widget.h" #include "QLoginDialog.h"#include <QDebug>Widget::Widget(QWidget *parent) : QWidget(parent), TestBtn(this) {TestBtn.setText("Test Login Dialog");setFixedSize(200, 50);connect(&TestBtn, SIGNAL(clicked()), this, SLOT(TestBtn_Clicked())); }void Widget::TestBtn_Clicked() {QLoginDialog dlg;if( dlg.exec() == QDialog::Accepted ){qDebug() << "User: " + dlg.getUser();qDebug() << "Pwd: " + dlg.getPwd();} }Widget::~Widget() {}

    main.cpp:

    #include <QtGui/QApplication> #include "widget.h"int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); }

    3 Qt種的標準對話框

    標準對話框:

    • Qt為開發者提供了一些可復用的對話框類型。
    • Qt提供的可復用對話框全部繼承自QDialog類。

      Qt中的標準對話框遵循相同的使用方式:

    參考資料:

  • QT實驗分析教程
  • 總結

    以上是生活随笔為你收集整理的Qt中的QDialog的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 好好热视频 | 成人黄色大片在线观看 | 婷婷资源网 | 秋霞网av| 国产剧情一区二区三区 | 亚洲三级色| 日韩在线视频中文字幕 | 狂躁美女大bbbbbb黑人 | 干骚视频| 欧美黑人xxx | 日b视频免费观看 | 日韩高清一区 | 三级成人 | 性欧美精品男男 | 99久久人妻无码精品系列 | 精品一区二区国产 | 国产高清久久 | 国产无套在线观看 | 日本一级网站 | 欧洲成人综合 | 久久露脸国语精品国产91 | 日韩一二三区在线观看 | 亚洲经典视频 | 少妇献身老头系列 | 久久午夜电影 | 亚洲最大网 | 美女视频国产 | 日本大胆欧美人术艺术 | 日本在线不卡一区 | 欧美亚洲中文精品字幕 | 波多野结衣一二三四区 | 色综合天天综合网天天狠天天 | 99爱爱 | 在线观看国产免费av | 黄在线免费 | 手机看片一区二区三区 | 涩涩涩涩涩涩涩涩涩 | 天堂在线亚洲 | 免费日韩成人 | 国产欧美一区二区三区四区 | 99riav视频 | 亚洲黄色在线观看视频 | 欧美精品一区视频 | 成人深夜在线观看 | 九九热最新视频 | 九九久久视频 | 永久免费无码av网站在线观看 | 成人爽a毛片一区二区 | 国产黄色免费网站 | 777精品伊人久久久久大香线蕉 | 久久精品无码一区二区三区免费 | 天堂av8在线 | 亚洲精品视频91 | 欧美色欧美 | 欧美有码在线 | 调教小屁屁白丝丨vk | 欧美成人三级在线 | 国产区久久 | 免费不卡av | 国内精品久久久久 | 狠狠操综合 | 91快色| 91在线欧美 | 色屁屁网站 | 国产精品成人免费精品自在线观看 | 国产熟女一区二区三区四区 | 久久亚洲AV成人无码一二三 | 91xxxxx| 精品人妻伦一二三区久 | 亚洲不卡在线视频 | 丁香六月婷婷 | 一区二区在线不卡 | 在线爱情大片免费观看大全 | 亚洲涩涩视频 | 成年人在线观看av | 嫩草导航 | 亚洲最大成人网色 | 丰满少妇麻豆av苏语棠 | 亚洲大尺度视频 | 久久精品免费播放 | 男人你懂的网站 | 国产无遮挡呻吟娇喘视频 | 欧美日韩麻豆 | 男女视频一区 | 99在线观看视频 | 国产精品电影一区 | 最新视频 - 88av | 欧美18av| 亚洲美女高潮久久久 | 精品久久久久久久久久久 | 日韩免费视频一区 | 98久久久| 成人永久免费 | 欧美成人乱码一区二区三区 | jizz日本在线 | 国产成人免费av一区二区午夜 | 色窝网 | 小俊大肉大捧一进一出好爽 | 性网|