Qt實(shí)現(xiàn)驗(yàn)證碼相關(guān)功能的代碼示例
驗(yàn)證碼的原理
驗(yàn)證碼的原理基于人類視覺(jué)和計(jì)算機(jī)視覺(jué)的差異性。通過(guò)給用戶顯示一些難以被機(jī)器識(shí)別的圖形或文字,讓用戶進(jìn)行人機(jī)交互,確認(rèn)自己的身份。這樣可以防止機(jī)器大規(guī)模注冊(cè)、機(jī)器暴力破解數(shù)據(jù)密碼等危害,保護(hù)網(wǎng)站安全。
Qt實(shí)現(xiàn)驗(yàn)證碼的原理
- 隨機(jī)性:驗(yàn)證碼必須是隨機(jī)生成的,以確保每次顯示的內(nèi)容都不同。
- 安全性:驗(yàn)證碼的生成過(guò)程需要考慮到安全性,例如使用不同的算法生成驗(yàn)證碼,避免被惡意程序破解。
- 用戶交互:驗(yàn)證碼生成后,需要由用戶進(jìn)行識(shí)別和填寫(xiě),通過(guò)用戶的操作來(lái)判斷用戶的有效性。
- 圖形界面:在Qt中,可以使用圖形界面組件來(lái)顯示驗(yàn)證碼,例如QLabel或QPushButton等。
- 圖像處理:為了增加驗(yàn)證碼的識(shí)別難度,可以在驗(yàn)證碼中添加噪聲、扭曲等效果,這需要使用圖像處理技術(shù)來(lái)實(shí)現(xiàn)。
實(shí)現(xiàn)步驟
- 創(chuàng)建UI界面:首先,在QT Designer中創(chuàng)建一個(gè)UI界面,添加一個(gè)Label標(biāo)簽,兩個(gè)Button按鈕以及一個(gè)lineEdit輸入框,并且將這些組件均放入widget樣式表當(dāng)中,并將widget樣式表放入centralwidget樣式表中。(在UI設(shè)計(jì)師界面可以使用SHIFT+ALT+R進(jìn)行預(yù)覽布局效果)


- 設(shè)置Label標(biāo)簽:將Label標(biāo)簽設(shè)置為顯示驗(yàn)證碼。你可以使用QLabel類來(lái)創(chuàng)建標(biāo)簽,并設(shè)置其文本屬性。
- 實(shí)現(xiàn)驗(yàn)證碼邏輯:編寫(xiě)代碼以生成驗(yàn)證碼。這通常涉及到一個(gè)隨機(jī)數(shù)生成器,用于生成一個(gè)唯一的驗(yàn)證碼字符串。
- 刷新驗(yàn)證碼:當(dāng)用戶點(diǎn)擊按鈕時(shí),重新生成一個(gè)新的驗(yàn)證碼,并更新Label標(biāo)簽的文本屬性。
- 驗(yàn)證驗(yàn)證碼:當(dāng)用戶提交表單時(shí),驗(yàn)證你所輸入的驗(yàn)證碼是否與Label標(biāo)簽上顯示的驗(yàn)證碼匹配。
具體代碼
- mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QTimer>
#include <QMessageBox>
#include <QPainter>
#include <QDebug>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
QString m_captcha;
QColor m_color;
void paintEvent(QPaintEvent* evt);
QString getCaptcha();
QColor generateRandomColor() ;
~MainWindow();
private slots:
void on_pushButton_clicked();
void on_pushButton_2_clicked();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H- main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}- mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QRandomGenerator>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
// 設(shè)置UI界面
m_captcha = getCaptcha();
// 獲取驗(yàn)證碼
m_color = generateRandomColor();
// 生成隨機(jī)顏色
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()//驗(yàn)證按鈕的槽函數(shù)
{
QString captcha = ui->lineEdit->text().replace(" ", "");
// 獲取用戶輸入的驗(yàn)證碼并去除空格
if(captcha.toLower() == m_captcha.toLower())
// 將用戶輸入的驗(yàn)證碼和生成的驗(yàn)證碼進(jìn)行比較(忽略大小寫(xiě))
{
QMessageBox::warning(this, "Warning", "Captcha is macthed");
// 如果驗(yàn)證碼匹配,顯示匹配提示框
}
else
{
QMessageBox::warning(this, "Warning", "Captcha is not macthed");
// 如果驗(yàn)證碼不匹配,顯示不匹配提示框
m_captcha = getCaptcha();
// 獲取新的驗(yàn)證碼
}
}
void MainWindow::on_pushButton_2_clicked()//刷新按鈕的槽函數(shù)
{
m_captcha = getCaptcha(); // 獲取新的驗(yàn)證碼
m_color = generateRandomColor(); // 生成隨機(jī)顏色
repaint(); // 重新繪制窗口
update(); // 更新窗口顯示
}
void MainWindow::paintEvent(QPaintEvent *evt)
{
QPainter painter(this);
// 填充背景為白色
painter.fillRect(ui->label->x()+ui->widget->x(), ui->label->y()+ui->widget->y(), ui->label->width(), ui->label->height(), Qt::white);
// 設(shè)置字體樣式
painter.setFont(QFont("Lucida Console", 18,QFont::Bold));
// 繪制驗(yàn)證碼字符
for(int i = 0; i < 4; i++)
{
QColor color = generateRandomColor();
// 生成隨機(jī)顏色
QPen pen(color);
pen.setWidth(1);
painter.setPen(pen);
painter.drawText(ui->label->x() +ui->widget->x()+ 30*i, ui->label->y()+ui->widget->y(), 30, ui->label->height(), Qt::AlignCenter,
QString(m_captcha[i]));
// 繪制驗(yàn)證碼字符
}
// 繪制噪點(diǎn)
for(int i=0; i<1500; i++)
{
QColor color = generateRandomColor();
// 生成隨機(jī)顏色
QPen pen(color);
pen.setWidth(1);
painter.setPen(pen);
painter.drawPoint(ui->label->x()+ui->widget->x()+ (qrand() % ui->label->width()), ui->label->y()+ui->widget->y() + (qrand() % ui->label->height()));
}
// 繪制干擾線
for(int i = 0;i < 10;++i)
{
painter.drawLine(ui->label->x()+ui->widget->x()+qrand()%ui->label->width(),ui->label->y()+ui->widget->y()+qrand()%ui->label->height(),
ui->label->x()+ui->widget->x()+qrand()%ui->label->width(),ui->label->y()+ui->widget->y()+qrand()%ui->label->height());
}
}
QString MainWindow::getCaptcha()
{
const QString possibleCharacters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
const int captchaLength = 4;
QString result = "";
// 生成驗(yàn)證碼字符串
for (int i = 0; i < captchaLength; ++i) {
int index = QRandomGenerator::global()->bounded(possibleCharacters.length());
// 生成一個(gè)0到possibleCharacters長(zhǎng)度之間的隨機(jī)整數(shù)
result.append(possibleCharacters.at(index));
// 將隨機(jī)位置的字符添加到結(jié)果字符串中
}
return result; // 返回生成的驗(yàn)證碼字符串
}
QColor MainWindow::generateRandomColor() {
int red = QRandomGenerator::global()->bounded(256);
// 生成0到255之間的隨機(jī)整數(shù)作為紅色通道的值
int green = QRandomGenerator::global()->bounded(256);
// 生成0到255之間的隨機(jī)整數(shù)作為綠色通道的值
int blue = QRandomGenerator::global()->bounded(256);
// 生成0到255之間的隨機(jī)整數(shù)作為藍(lán)色通道的值
return QColor(red, green, blue);
// 使用生成的RGB值創(chuàng)建并返回一個(gè)QColor對(duì)象
}
相關(guān)代碼的注解
fillRect的相關(guān)用法
- 在Qt的QPainter類中,fillRect()函數(shù)用于填充矩形。它需要兩個(gè)參數(shù):一個(gè)QRect對(duì)象和QBrush對(duì)象。
- QRect對(duì)象定義了矩形的位置和大小,而QBrush對(duì)象則定義了矩形的填充方式。我們可以將QColor對(duì)象作為刷子傳遞給這個(gè)函數(shù),以指定實(shí)填充模式。
- 如果顏色不是完全的不透明(即alpha通道值小于255),則先繪制白色背景,然后使用fillRect()函數(shù)填充矩形。因此,fillRect()函數(shù)的參數(shù)含義為:第一個(gè)參數(shù)是一個(gè)QRect對(duì)象,表示要填充的矩形區(qū)域。它包含了矩形的左上角坐標(biāo)(x, y)和其寬度和高度(width, height)。第二個(gè)參數(shù)是一個(gè)QBrush對(duì)象,表示填充矩形的樣式??梢詫Color對(duì)象作為刷子傳遞給這個(gè)函數(shù),以指定實(shí)填充模式。
示例代碼
void MyWidget::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
QRect rect(10, 10, 100, 50); // 定義一個(gè)矩形區(qū)域
QColor color(255, 0, 0); // 定義紅色
painter.fillRect(rect, color); // 填充矩形
}在上述示例中,我們定義了一個(gè)矩形區(qū)域 rect,左上角坐標(biāo)為 (10, 10),寬度為 100,高度為 50。然后,我們使用 fillRect 方法填充該矩形區(qū)域?yàn)榧t色。
對(duì)于上述代碼mainwindow.cpp中的painter.fillRect(ui->label->x()+ui->widget->x(), ui->label->y()+ui->widget->y(), ui->label->width(), ui->label->height(), Qt::white);解釋
如圖所示

相當(dāng)于求A點(diǎn)相當(dāng)于C點(diǎn)的坐標(biāo),也就是將B點(diǎn)相對(duì)于C點(diǎn)的坐標(biāo)+A點(diǎn)相對(duì)于B點(diǎn)的坐標(biāo) 即A點(diǎn)相當(dāng)于C點(diǎn)的坐標(biāo)為(ui->label->x()+ui->widget->x(), ui->label->y()+ui->widget->y())
效果圖
- 初始界面

- 驗(yàn)證成功

- 驗(yàn)證失敗

- 刷新驗(yàn)證碼

最后
以上就是Qt實(shí)現(xiàn)驗(yàn)證碼相關(guān)功能的代碼示例的詳細(xì)內(nèi)容,更多關(guān)于Qt實(shí)現(xiàn)驗(yàn)證碼功能的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
用C語(yǔ)言實(shí)現(xiàn)猜數(shù)字游戲
這篇文章主要為大家詳細(xì)介紹了用C語(yǔ)言實(shí)現(xiàn)猜數(shù)字游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-10-10
opencv實(shí)現(xiàn)像素統(tǒng)計(jì)的示例代碼
本文介紹了OpenCV中統(tǒng)計(jì)圖像像素信息的常用方法和函數(shù),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2025-01-01
簡(jiǎn)單掌握桶排序算法及C++版的代碼實(shí)現(xiàn)
桶排序是將要排序的算法按桶分組排序之后再遍歷匯總的一種線性排序算法,下面就讓我們來(lái)通過(guò)小例子簡(jiǎn)單掌握桶排序算法及C++版的代碼實(shí)現(xiàn)^^2016-07-07
C語(yǔ)言開(kāi)發(fā)實(shí)現(xiàn)貪吃蛇游戲
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言開(kāi)發(fā)實(shí)現(xiàn)貪吃蛇游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-07-07
C++學(xué)習(xí)之算術(shù)運(yùn)算符使用詳解
運(yùn)算符是計(jì)算機(jī)語(yǔ)言提供的能對(duì)數(shù)據(jù)進(jìn)行基本運(yùn)算操作的功能體。而算術(shù)運(yùn)算符用來(lái)對(duì)數(shù)字型數(shù)據(jù)進(jìn)行數(shù)學(xué)語(yǔ)義上的加、減、乘、除。本文通過(guò)講解清楚算術(shù)運(yùn)算符,讓大家了解使用C++運(yùn)算符時(shí)應(yīng)該注意的事項(xiàng)2022-06-06
C/C++ Qt 基本文件讀寫(xiě)的基本使用(2種實(shí)現(xiàn))
文件的讀寫(xiě)是很多應(yīng)用程序具有的功能,本文主要介紹了兩種實(shí)現(xiàn)方法,第一種使用QFile類的IODevice讀寫(xiě)功能直接讀寫(xiě),第二種是利用 QFile和QTextStream結(jié)合起來(lái),用流的方式進(jìn)行文件讀寫(xiě)2021-11-11

