Compare commits
15 Commits
1424dc8874
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
| a0ea598880 | |||
| 3fb8491555 | |||
| f7ba76c56f | |||
| 6f894cb9b1 | |||
| de36ac8b3c | |||
| fc4b1e799b | |||
| 3d5f265596 | |||
| 554a5f12d0 | |||
| f36cc5ce97 | |||
| 5bcb4c519d | |||
| 1c2e268a52 | |||
| e7d3739038 | |||
| 98bb2cf0f1 | |||
| 4295013896 | |||
| 4c474d31c5 |
@@ -93,4 +93,566 @@ dkms.conf
|
|||||||
*.o
|
*.o
|
||||||
*.swp
|
*.swp
|
||||||
.vscode
|
.vscode
|
||||||
*/test
|
*/test
|
||||||
|
|
||||||
|
# ---> Qt
|
||||||
|
# C++ objects and libs
|
||||||
|
*.slo
|
||||||
|
*.lo
|
||||||
|
*.o
|
||||||
|
*.a
|
||||||
|
*.la
|
||||||
|
*.lai
|
||||||
|
*.so
|
||||||
|
*.so.*
|
||||||
|
*.dll
|
||||||
|
*.dylib
|
||||||
|
|
||||||
|
# Qt-es
|
||||||
|
object_script.*.Release
|
||||||
|
object_script.*.Debug
|
||||||
|
*_plugin_import.cpp
|
||||||
|
/.qmake.cache
|
||||||
|
.qmake.cache
|
||||||
|
/.qmake.stash
|
||||||
|
.qmake.stash
|
||||||
|
*.pro.user
|
||||||
|
*.pro.user.*
|
||||||
|
*.qbs.user
|
||||||
|
*.qbs.user.*
|
||||||
|
*.moc
|
||||||
|
moc_*.cpp
|
||||||
|
moc_*.h
|
||||||
|
qrc_*.cpp
|
||||||
|
ui_*.h
|
||||||
|
*.qmlc
|
||||||
|
*.jsc
|
||||||
|
#Makefile*
|
||||||
|
*build-*
|
||||||
|
*.qm
|
||||||
|
*.prl
|
||||||
|
|
||||||
|
# Qt unit tests
|
||||||
|
target_wrapper.*
|
||||||
|
|
||||||
|
# QtCreator
|
||||||
|
*.autosave
|
||||||
|
|
||||||
|
# QtCreator Qml
|
||||||
|
*.qmlproject.user
|
||||||
|
*.qmlproject.user.*
|
||||||
|
|
||||||
|
# QtCreator CMake
|
||||||
|
CMakeLists.txt.user*
|
||||||
|
|
||||||
|
# QtCreator 4.8< compilation database
|
||||||
|
compile_commands.json
|
||||||
|
|
||||||
|
# QtCreator local machine specific files for imported projects
|
||||||
|
*creator.user*
|
||||||
|
|
||||||
|
*_qmlcache.qrc
|
||||||
|
|
||||||
|
# ---> VisualStudio
|
||||||
|
## Ignore Visual Studio temporary files, build results, and
|
||||||
|
## files generated by popular Visual Studio add-ons.
|
||||||
|
##
|
||||||
|
## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore
|
||||||
|
|
||||||
|
# User-specific files
|
||||||
|
*.rsuser
|
||||||
|
*.suo
|
||||||
|
*.user
|
||||||
|
*.userosscache
|
||||||
|
*.sln.docstates
|
||||||
|
|
||||||
|
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||||
|
*.userprefs
|
||||||
|
|
||||||
|
# Mono auto generated files
|
||||||
|
mono_crash.*
|
||||||
|
|
||||||
|
# Build results
|
||||||
|
[Dd]ebug/
|
||||||
|
[Dd]ebugPublic/
|
||||||
|
[Rr]elease/
|
||||||
|
[Rr]eleases/
|
||||||
|
x64/
|
||||||
|
x86/
|
||||||
|
[Ww][Ii][Nn]32/
|
||||||
|
[Aa][Rr][Mm]/
|
||||||
|
[Aa][Rr][Mm]64/
|
||||||
|
bld/
|
||||||
|
[Bb]in/
|
||||||
|
[Oo]bj/
|
||||||
|
[Ll]og/
|
||||||
|
[Ll]ogs/
|
||||||
|
|
||||||
|
# Visual Studio 2015/2017 cache/options directory
|
||||||
|
.vs/
|
||||||
|
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||||
|
#wwwroot/
|
||||||
|
|
||||||
|
# Visual Studio 2017 auto generated files
|
||||||
|
Generated\ Files/
|
||||||
|
|
||||||
|
# MSTest test Results
|
||||||
|
[Tt]est[Rr]esult*/
|
||||||
|
[Bb]uild[Ll]og.*
|
||||||
|
|
||||||
|
# NUnit
|
||||||
|
*.VisualState.xml
|
||||||
|
TestResult.xml
|
||||||
|
nunit-*.xml
|
||||||
|
|
||||||
|
# Build Results of an ATL Project
|
||||||
|
[Dd]ebugPS/
|
||||||
|
[Rr]eleasePS/
|
||||||
|
dlldata.c
|
||||||
|
|
||||||
|
# Benchmark Results
|
||||||
|
BenchmarkDotNet.Artifacts/
|
||||||
|
|
||||||
|
# .NET Core
|
||||||
|
project.lock.json
|
||||||
|
project.fragment.lock.json
|
||||||
|
artifacts/
|
||||||
|
|
||||||
|
# ASP.NET Scaffolding
|
||||||
|
ScaffoldingReadMe.txt
|
||||||
|
|
||||||
|
# StyleCop
|
||||||
|
StyleCopReport.xml
|
||||||
|
|
||||||
|
# Files built by Visual Studio
|
||||||
|
*_i.c
|
||||||
|
*_p.c
|
||||||
|
*_h.h
|
||||||
|
*.ilk
|
||||||
|
*.meta
|
||||||
|
*.obj
|
||||||
|
*.iobj
|
||||||
|
*.pch
|
||||||
|
*.pdb
|
||||||
|
*.ipdb
|
||||||
|
*.pgc
|
||||||
|
*.pgd
|
||||||
|
*.rsp
|
||||||
|
*.sbr
|
||||||
|
*.tlb
|
||||||
|
*.tli
|
||||||
|
*.tlh
|
||||||
|
*.tmp
|
||||||
|
*.tmp_proj
|
||||||
|
*_wpftmp.csproj
|
||||||
|
*.log
|
||||||
|
*.tlog
|
||||||
|
*.vspscc
|
||||||
|
*.vssscc
|
||||||
|
.builds
|
||||||
|
*.pidb
|
||||||
|
*.svclog
|
||||||
|
*.scc
|
||||||
|
|
||||||
|
# Chutzpah Test files
|
||||||
|
_Chutzpah*
|
||||||
|
|
||||||
|
# Visual C++ cache files
|
||||||
|
ipch/
|
||||||
|
*.aps
|
||||||
|
*.ncb
|
||||||
|
*.opendb
|
||||||
|
*.opensdf
|
||||||
|
*.sdf
|
||||||
|
*.cachefile
|
||||||
|
*.VC.db
|
||||||
|
*.VC.VC.opendb
|
||||||
|
|
||||||
|
# Visual Studio profiler
|
||||||
|
*.psess
|
||||||
|
*.vsp
|
||||||
|
*.vspx
|
||||||
|
*.sap
|
||||||
|
|
||||||
|
# Visual Studio Trace Files
|
||||||
|
*.e2e
|
||||||
|
|
||||||
|
# TFS 2012 Local Workspace
|
||||||
|
$tf/
|
||||||
|
|
||||||
|
# Guidance Automation Toolkit
|
||||||
|
*.gpState
|
||||||
|
|
||||||
|
# ReSharper is a .NET coding add-in
|
||||||
|
_ReSharper*/
|
||||||
|
*.[Rr]e[Ss]harper
|
||||||
|
*.DotSettings.user
|
||||||
|
|
||||||
|
# TeamCity is a build add-in
|
||||||
|
_TeamCity*
|
||||||
|
|
||||||
|
# DotCover is a Code Coverage Tool
|
||||||
|
*.dotCover
|
||||||
|
|
||||||
|
# AxoCover is a Code Coverage Tool
|
||||||
|
.axoCover/*
|
||||||
|
!.axoCover/settings.json
|
||||||
|
|
||||||
|
# Coverlet is a free, cross platform Code Coverage Tool
|
||||||
|
coverage*.json
|
||||||
|
coverage*.xml
|
||||||
|
coverage*.info
|
||||||
|
|
||||||
|
# Visual Studio code coverage results
|
||||||
|
*.coverage
|
||||||
|
*.coveragexml
|
||||||
|
|
||||||
|
# NCrunch
|
||||||
|
_NCrunch_*
|
||||||
|
.*crunch*.local.xml
|
||||||
|
nCrunchTemp_*
|
||||||
|
|
||||||
|
# MightyMoose
|
||||||
|
*.mm.*
|
||||||
|
AutoTest.Net/
|
||||||
|
|
||||||
|
# Web workbench (sass)
|
||||||
|
.sass-cache/
|
||||||
|
|
||||||
|
# Installshield output folder
|
||||||
|
[Ee]xpress/
|
||||||
|
|
||||||
|
# DocProject is a documentation generator add-in
|
||||||
|
DocProject/buildhelp/
|
||||||
|
DocProject/Help/*.HxT
|
||||||
|
DocProject/Help/*.HxC
|
||||||
|
DocProject/Help/*.hhc
|
||||||
|
DocProject/Help/*.hhk
|
||||||
|
DocProject/Help/*.hhp
|
||||||
|
DocProject/Help/Html2
|
||||||
|
DocProject/Help/html
|
||||||
|
|
||||||
|
# Click-Once directory
|
||||||
|
publish/
|
||||||
|
|
||||||
|
# Publish Web Output
|
||||||
|
*.[Pp]ublish.xml
|
||||||
|
*.azurePubxml
|
||||||
|
# Note: Comment the next line if you want to checkin your web deploy settings,
|
||||||
|
# but database connection strings (with potential passwords) will be unencrypted
|
||||||
|
*.pubxml
|
||||||
|
*.publishproj
|
||||||
|
|
||||||
|
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
||||||
|
# checkin your Azure Web App publish settings, but sensitive information contained
|
||||||
|
# in these scripts will be unencrypted
|
||||||
|
PublishScripts/
|
||||||
|
|
||||||
|
# NuGet Packages
|
||||||
|
*.nupkg
|
||||||
|
# NuGet Symbol Packages
|
||||||
|
*.snupkg
|
||||||
|
# The packages folder can be ignored because of Package Restore
|
||||||
|
**/[Pp]ackages/*
|
||||||
|
# except build/, which is used as an MSBuild target.
|
||||||
|
!**/[Pp]ackages/build/
|
||||||
|
# Uncomment if necessary however generally it will be regenerated when needed
|
||||||
|
#!**/[Pp]ackages/repositories.config
|
||||||
|
# NuGet v3's project.json files produces more ignorable files
|
||||||
|
*.nuget.props
|
||||||
|
*.nuget.targets
|
||||||
|
|
||||||
|
# Microsoft Azure Build Output
|
||||||
|
csx/
|
||||||
|
*.build.csdef
|
||||||
|
|
||||||
|
# Microsoft Azure Emulator
|
||||||
|
ecf/
|
||||||
|
rcf/
|
||||||
|
|
||||||
|
# Windows Store app package directories and files
|
||||||
|
AppPackages/
|
||||||
|
BundleArtifacts/
|
||||||
|
Package.StoreAssociation.xml
|
||||||
|
_pkginfo.txt
|
||||||
|
*.appx
|
||||||
|
*.appxbundle
|
||||||
|
*.appxupload
|
||||||
|
|
||||||
|
# Visual Studio cache files
|
||||||
|
# files ending in .cache can be ignored
|
||||||
|
*.[Cc]ache
|
||||||
|
# but keep track of directories ending in .cache
|
||||||
|
!?*.[Cc]ache/
|
||||||
|
|
||||||
|
# Others
|
||||||
|
ClientBin/
|
||||||
|
~$*
|
||||||
|
*~
|
||||||
|
*.dbmdl
|
||||||
|
*.dbproj.schemaview
|
||||||
|
*.jfm
|
||||||
|
*.pfx
|
||||||
|
*.publishsettings
|
||||||
|
orleans.codegen.cs
|
||||||
|
|
||||||
|
# Including strong name files can present a security risk
|
||||||
|
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
|
||||||
|
#*.snk
|
||||||
|
|
||||||
|
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
||||||
|
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||||
|
#bower_components/
|
||||||
|
|
||||||
|
# RIA/Silverlight projects
|
||||||
|
Generated_Code/
|
||||||
|
|
||||||
|
# Backup & report files from converting an old project file
|
||||||
|
# to a newer Visual Studio version. Backup files are not needed,
|
||||||
|
# because we have git ;-)
|
||||||
|
_UpgradeReport_Files/
|
||||||
|
Backup*/
|
||||||
|
UpgradeLog*.XML
|
||||||
|
UpgradeLog*.htm
|
||||||
|
ServiceFabricBackup/
|
||||||
|
*.rptproj.bak
|
||||||
|
|
||||||
|
# SQL Server files
|
||||||
|
*.mdf
|
||||||
|
*.ldf
|
||||||
|
*.ndf
|
||||||
|
|
||||||
|
# Business Intelligence projects
|
||||||
|
*.rdl.data
|
||||||
|
*.bim.layout
|
||||||
|
*.bim_*.settings
|
||||||
|
*.rptproj.rsuser
|
||||||
|
*- [Bb]ackup.rdl
|
||||||
|
*- [Bb]ackup ([0-9]).rdl
|
||||||
|
*- [Bb]ackup ([0-9][0-9]).rdl
|
||||||
|
|
||||||
|
# Microsoft Fakes
|
||||||
|
FakesAssemblies/
|
||||||
|
|
||||||
|
# GhostDoc plugin setting file
|
||||||
|
*.GhostDoc.xml
|
||||||
|
|
||||||
|
# Node.js Tools for Visual Studio
|
||||||
|
.ntvs_analysis.dat
|
||||||
|
node_modules/
|
||||||
|
|
||||||
|
# Visual Studio 6 build log
|
||||||
|
*.plg
|
||||||
|
|
||||||
|
# Visual Studio 6 workspace options file
|
||||||
|
*.opt
|
||||||
|
|
||||||
|
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
|
||||||
|
*.vbw
|
||||||
|
|
||||||
|
# Visual Studio 6 auto-generated project file (contains which files were open etc.)
|
||||||
|
*.vbp
|
||||||
|
|
||||||
|
# Visual Studio 6 workspace and project file (working project files containing files to include in project)
|
||||||
|
*.dsw
|
||||||
|
*.dsp
|
||||||
|
|
||||||
|
# Visual Studio 6 technical files
|
||||||
|
*.ncb
|
||||||
|
*.aps
|
||||||
|
|
||||||
|
# Visual Studio LightSwitch build output
|
||||||
|
**/*.HTMLClient/GeneratedArtifacts
|
||||||
|
**/*.DesktopClient/GeneratedArtifacts
|
||||||
|
**/*.DesktopClient/ModelManifest.xml
|
||||||
|
**/*.Server/GeneratedArtifacts
|
||||||
|
**/*.Server/ModelManifest.xml
|
||||||
|
_Pvt_Extensions
|
||||||
|
|
||||||
|
# Paket dependency manager
|
||||||
|
.paket/paket.exe
|
||||||
|
paket-files/
|
||||||
|
|
||||||
|
# FAKE - F# Make
|
||||||
|
.fake/
|
||||||
|
|
||||||
|
# CodeRush personal settings
|
||||||
|
.cr/personal
|
||||||
|
|
||||||
|
# Python Tools for Visual Studio (PTVS)
|
||||||
|
__pycache__/
|
||||||
|
*.pyc
|
||||||
|
|
||||||
|
# Cake - Uncomment if you are using it
|
||||||
|
# tools/**
|
||||||
|
# !tools/packages.config
|
||||||
|
|
||||||
|
# Tabs Studio
|
||||||
|
*.tss
|
||||||
|
|
||||||
|
# Telerik's JustMock configuration file
|
||||||
|
*.jmconfig
|
||||||
|
|
||||||
|
# BizTalk build output
|
||||||
|
*.btp.cs
|
||||||
|
*.btm.cs
|
||||||
|
*.odx.cs
|
||||||
|
*.xsd.cs
|
||||||
|
|
||||||
|
# OpenCover UI analysis results
|
||||||
|
OpenCover/
|
||||||
|
|
||||||
|
# Azure Stream Analytics local run output
|
||||||
|
ASALocalRun/
|
||||||
|
|
||||||
|
# MSBuild Binary and Structured Log
|
||||||
|
*.binlog
|
||||||
|
|
||||||
|
# NVidia Nsight GPU debugger configuration file
|
||||||
|
*.nvuser
|
||||||
|
|
||||||
|
# MFractors (Xamarin productivity tool) working folder
|
||||||
|
.mfractor/
|
||||||
|
|
||||||
|
# Local History for Visual Studio
|
||||||
|
.localhistory/
|
||||||
|
|
||||||
|
# Visual Studio History (VSHistory) files
|
||||||
|
.vshistory/
|
||||||
|
|
||||||
|
# BeatPulse healthcheck temp database
|
||||||
|
healthchecksdb
|
||||||
|
|
||||||
|
# Backup folder for Package Reference Convert tool in Visual Studio 2017
|
||||||
|
MigrationBackup/
|
||||||
|
|
||||||
|
# Ionide (cross platform F# VS Code tools) working folder
|
||||||
|
.ionide/
|
||||||
|
|
||||||
|
# Fody - auto-generated XML schema
|
||||||
|
FodyWeavers.xsd
|
||||||
|
|
||||||
|
# VS Code files for those working on multiple tools
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/settings.json
|
||||||
|
!.vscode/tasks.json
|
||||||
|
!.vscode/launch.json
|
||||||
|
!.vscode/extensions.json
|
||||||
|
*.code-workspace
|
||||||
|
|
||||||
|
# Local History for Visual Studio Code
|
||||||
|
.history/
|
||||||
|
|
||||||
|
# Windows Installer files from build outputs
|
||||||
|
*.cab
|
||||||
|
*.msi
|
||||||
|
*.msix
|
||||||
|
*.msm
|
||||||
|
*.msp
|
||||||
|
|
||||||
|
# JetBrains Rider
|
||||||
|
*.sln.iml
|
||||||
|
|
||||||
|
# ---> VisualStudioCode
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/settings.json
|
||||||
|
!.vscode/tasks.json
|
||||||
|
!.vscode/launch.json
|
||||||
|
!.vscode/extensions.json
|
||||||
|
!.vscode/*.code-snippets
|
||||||
|
|
||||||
|
# Local History for Visual Studio Code
|
||||||
|
.history/
|
||||||
|
|
||||||
|
# Built Visual Studio Code Extensions
|
||||||
|
*.vsix
|
||||||
|
|
||||||
|
# ---> C
|
||||||
|
# Prerequisites
|
||||||
|
*.d
|
||||||
|
|
||||||
|
# Object files
|
||||||
|
*.o
|
||||||
|
*.ko
|
||||||
|
*.obj
|
||||||
|
*.elf
|
||||||
|
|
||||||
|
# Linker output
|
||||||
|
*.ilk
|
||||||
|
*.map
|
||||||
|
*.exp
|
||||||
|
|
||||||
|
# Precompiled Headers
|
||||||
|
*.gch
|
||||||
|
*.pch
|
||||||
|
|
||||||
|
# Libraries
|
||||||
|
*.lib
|
||||||
|
*.a
|
||||||
|
*.la
|
||||||
|
*.lo
|
||||||
|
|
||||||
|
# Shared objects (inc. Windows DLLs)
|
||||||
|
*.dll
|
||||||
|
*.so
|
||||||
|
*.so.*
|
||||||
|
*.dylib
|
||||||
|
|
||||||
|
# Executables
|
||||||
|
*.exe
|
||||||
|
*.out
|
||||||
|
*.app
|
||||||
|
*.i*86
|
||||||
|
*.x86_64
|
||||||
|
*.hex
|
||||||
|
|
||||||
|
# Debug files
|
||||||
|
*.dSYM/
|
||||||
|
*.su
|
||||||
|
*.idb
|
||||||
|
*.pdb
|
||||||
|
|
||||||
|
# Kernel Module Compile Results
|
||||||
|
*.mod*
|
||||||
|
*.cmd
|
||||||
|
.tmp_versions/
|
||||||
|
modules.order
|
||||||
|
Module.symvers
|
||||||
|
Mkfile.old
|
||||||
|
dkms.conf
|
||||||
|
|
||||||
|
# ---> C++
|
||||||
|
# Prerequisites
|
||||||
|
*.d
|
||||||
|
|
||||||
|
# Compiled Object files
|
||||||
|
*.slo
|
||||||
|
*.lo
|
||||||
|
*.o
|
||||||
|
*.obj
|
||||||
|
|
||||||
|
# Precompiled Headers
|
||||||
|
*.gch
|
||||||
|
*.pch
|
||||||
|
|
||||||
|
# Compiled Dynamic libraries
|
||||||
|
*.so
|
||||||
|
*.dylib
|
||||||
|
*.dll
|
||||||
|
|
||||||
|
# Fortran module files
|
||||||
|
*.mod
|
||||||
|
*.smod
|
||||||
|
|
||||||
|
# Compiled Static libraries
|
||||||
|
*.lai
|
||||||
|
*.la
|
||||||
|
*.a
|
||||||
|
*.lib
|
||||||
|
|
||||||
|
# Executables
|
||||||
|
*.exe
|
||||||
|
*.out
|
||||||
|
*.app
|
||||||
|
|
||||||
|
.vscode
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
#include "widget.h"
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
// 1. Qt 应用程序
|
||||||
|
QApplication a(argc, argv);
|
||||||
|
|
||||||
|
// 2. 应用程序中显示的主窗口
|
||||||
|
Widget w;
|
||||||
|
w.show();
|
||||||
|
|
||||||
|
// 3. 启动 Qt 程序, 监听窗口的相关事件
|
||||||
|
// 直到窗口关闭事件发生才退出
|
||||||
|
return a.exec(); // a.exec 的目的是保持程序活着
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
QT += core gui
|
||||||
|
|
||||||
|
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||||
|
|
||||||
|
CONFIG += c++11
|
||||||
|
|
||||||
|
# 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 \
|
||||||
|
widget.cpp
|
||||||
|
|
||||||
|
HEADERS += \
|
||||||
|
widget.h
|
||||||
|
|
||||||
|
# Default rules for deployment.
|
||||||
|
qnx: target.path = /tmp/$${TARGET}/bin
|
||||||
|
else: unix:!android: target.path = /opt/$${TARGET}/bin
|
||||||
|
!isEmpty(target.path): INSTALLS += target
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
#include "widget.h"
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QPushButton>
|
||||||
|
|
||||||
|
Widget::Widget(QWidget *parent)
|
||||||
|
: QWidget(parent)
|
||||||
|
{
|
||||||
|
this->setWindowTitle("我是第一个小窗口");
|
||||||
|
|
||||||
|
// this -> resize(200,300);
|
||||||
|
|
||||||
|
this->setFixedSize(QSize(480, 320));
|
||||||
|
|
||||||
|
// 创建一个按钮
|
||||||
|
// c++中创建类对象的两种方式:
|
||||||
|
// 1) 类名 对象 (构造函数的)
|
||||||
|
QPushButton *btn = new QPushButton("退出");
|
||||||
|
btn->resize(100, 50); // 设置控件的大小
|
||||||
|
btn->setParent(this); // 设置控件在哪一个窗口显示
|
||||||
|
|
||||||
|
btn->move(190, 135);
|
||||||
|
|
||||||
|
// connect(btn,&QPushButton::clicked,this,&QApplication::quit);
|
||||||
|
connect(btn, &QPushButton::clicked, this, &QWidget::close);
|
||||||
|
|
||||||
|
QPushButton *btn2 = new QPushButton("2");
|
||||||
|
btn2->resize(100, 50); // 设置控件的大小
|
||||||
|
btn2->setParent(this); // 设置控件在哪一个窗口显示
|
||||||
|
|
||||||
|
btn2->move(190 + 100, 135);
|
||||||
|
|
||||||
|
QPushButton *btn3 = new QPushButton("3");
|
||||||
|
btn3->resize(100, 50); // 设置控件的大小
|
||||||
|
btn3->setParent(this); // 设置控件在哪一个窗口显示
|
||||||
|
|
||||||
|
btn3->move(190 + 200, 135);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget::~Widget()
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
#ifndef WIDGET_H
|
||||||
|
#define WIDGET_H
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
class Widget : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
Widget(QWidget *parent = nullptr);
|
||||||
|
~Widget();
|
||||||
|
};
|
||||||
|
#endif // WIDGET_H
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
#include "widget.h"
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
QApplication a(argc, argv);
|
||||||
|
Widget w;
|
||||||
|
w.show();
|
||||||
|
return a.exec();
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
QT += core gui
|
||||||
|
|
||||||
|
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||||
|
|
||||||
|
CONFIG += c++11
|
||||||
|
|
||||||
|
# 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 \
|
||||||
|
widget.cpp
|
||||||
|
|
||||||
|
HEADERS += \
|
||||||
|
widget.h
|
||||||
|
|
||||||
|
# Default rules for deployment.
|
||||||
|
qnx: target.path = /tmp/$${TARGET}/bin
|
||||||
|
else: unix:!android: target.path = /opt/$${TARGET}/bin
|
||||||
|
!isEmpty(target.path): INSTALLS += target
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
#include "widget.h"
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
|
||||||
|
Widget::Widget(QWidget *parent)
|
||||||
|
: QWidget(parent)
|
||||||
|
{
|
||||||
|
setWindowTitle("加法计数器");
|
||||||
|
|
||||||
|
setFixedSize(500,100);
|
||||||
|
|
||||||
|
QPushButton *sumBtn=new QPushButton("计算",this);
|
||||||
|
sumBtn->setFixedSize(100,50);
|
||||||
|
sumBtn->move(300,25);
|
||||||
|
|
||||||
|
le1 = new QLineEdit(this);
|
||||||
|
le2 = new QLineEdit(this);
|
||||||
|
le1->setFixedSize(100,50);
|
||||||
|
le2->setFixedSize(100,50);
|
||||||
|
le1->move(0,25);
|
||||||
|
le2->move(200,25);
|
||||||
|
|
||||||
|
lable1 = new QLabel(this);
|
||||||
|
lable1->setText("+");
|
||||||
|
lable1->setFixedSize(10,50);
|
||||||
|
lable1->move(145,25);
|
||||||
|
|
||||||
|
lable2 = new QLabel(this);
|
||||||
|
lable2->setText("计算结果");
|
||||||
|
lable2->setFixedSize(100,50);
|
||||||
|
lable2->move(400,25);
|
||||||
|
|
||||||
|
connect(sumBtn,&QPushButton::clicked,this,&Widget::sum);
|
||||||
|
|
||||||
|
|
||||||
|
// connect(sumBtn,&QPushButton::clicked,this,lable2->setText(QString::number(c)));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Widget::sum(){
|
||||||
|
lable2->setText("点击");
|
||||||
|
QString n1 = le1->text();
|
||||||
|
QString n2 = le2->text();
|
||||||
|
qDebug() << n1 << " " << n2;
|
||||||
|
|
||||||
|
// 将文本转化为数值
|
||||||
|
int ret = n1.toInt()+n2.toInt();
|
||||||
|
QString str = QString::number(ret);
|
||||||
|
qDebug() << str;
|
||||||
|
lable2->setText(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget::~Widget()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
#ifndef WIDGET_H
|
||||||
|
#define WIDGET_H
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
#include <iostream>
|
||||||
|
#include <QPushButton> // 按钮
|
||||||
|
#include <QLineEdit> // 文本输入框
|
||||||
|
#include <QLabel> // 文本标签
|
||||||
|
|
||||||
|
class Widget : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
Widget(QWidget *parent = nullptr);
|
||||||
|
~Widget();
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
// 自定义槽函数, 需要在源文件中去实现函数功能
|
||||||
|
void sum();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QLineEdit *le1,*le2;
|
||||||
|
QLabel *lable1,*lable2;
|
||||||
|
|
||||||
|
};
|
||||||
|
#endif // WIDGET_H
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
#include "widget.h"
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
QApplication a(argc, argv);
|
||||||
|
Widget w;
|
||||||
|
w.show();
|
||||||
|
return a.exec();
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
QT += core gui
|
||||||
|
|
||||||
|
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||||
|
|
||||||
|
CONFIG += c++11
|
||||||
|
|
||||||
|
# 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 \
|
||||||
|
student.cpp \
|
||||||
|
teacher.cpp \
|
||||||
|
widget.cpp
|
||||||
|
|
||||||
|
HEADERS += \
|
||||||
|
student.h \
|
||||||
|
teacher.h \
|
||||||
|
widget.h
|
||||||
|
|
||||||
|
TARGET = moneyorno
|
||||||
|
# Default rules for deployment.
|
||||||
|
qnx: target.path = /tmp/$${TARGET}/bin
|
||||||
|
else: unix:!android: target.path = /opt/$${TARGET}/bin
|
||||||
|
!isEmpty(target.path): INSTALLS += target
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
#include "student.h"
|
||||||
|
|
||||||
|
Student::Student(QWidget *parent) : QWidget(parent)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Student::drink()
|
||||||
|
{
|
||||||
|
qDebug() << "请老师吃冷饮" << endl;
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
#ifndef STUDENT_H
|
||||||
|
#define STUDENT_H
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
class Student : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit Student(QWidget *parent = nullptr);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void drink();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // STUDENT_H
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#include "teacher.h"
|
||||||
|
|
||||||
|
Teacher::Teacher(QWidget *parent) : QWidget(parent)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
#ifndef TEACHER_H
|
||||||
|
#define TEACHER_H
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
class Teacher : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit Teacher(QWidget *parent = nullptr);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void hot();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // TEACHER_H
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
#include "widget.h"
|
||||||
|
|
||||||
|
Widget::Widget(QWidget *parent)
|
||||||
|
: QWidget(parent)
|
||||||
|
{
|
||||||
|
resize(500,300);
|
||||||
|
setWindowTitle("热了与冷饮");
|
||||||
|
n=0;
|
||||||
|
|
||||||
|
btn = new QPushButton("热了",this);
|
||||||
|
btn->setFixedSize(100,50);
|
||||||
|
btn->move(100,100);
|
||||||
|
|
||||||
|
btn2 = new QPushButton("没钱了",this);
|
||||||
|
btn2->setFixedSize(100,50);
|
||||||
|
btn2->move(100,200);
|
||||||
|
|
||||||
|
lable1 = new QLabel("显示",this);
|
||||||
|
lable1->setFixedSize(200,50);
|
||||||
|
lable1->move(250,100);
|
||||||
|
|
||||||
|
lable2 = new QLabel("请客次数: ",this);
|
||||||
|
lable2->setFixedSize(200,50);
|
||||||
|
lable2->move(250,200);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
t1 = new Teacher();
|
||||||
|
s1 = new Student();
|
||||||
|
|
||||||
|
connect(t1,&Teacher::hot,s1,&Student::drink);
|
||||||
|
connect(btn,&QPushButton::clicked,this,&Widget::handleHot);
|
||||||
|
connect(btn2,&QPushButton::clicked,this,&Widget::noMoney);
|
||||||
|
|
||||||
|
|
||||||
|
emit t1->hot();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Widget::handleHot()
|
||||||
|
{
|
||||||
|
emit t1->hot();
|
||||||
|
Widget::print();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Widget::print()
|
||||||
|
{
|
||||||
|
|
||||||
|
n++;
|
||||||
|
if(n>0){
|
||||||
|
if(n%2==0)
|
||||||
|
lable1->setText("请老师吃巧乐兹");
|
||||||
|
else
|
||||||
|
lable1->setText("请老师吃老冰棍");
|
||||||
|
lable2->setText("请客次数: "+QString::number(n));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Widget::noMoney()
|
||||||
|
{
|
||||||
|
n=0;
|
||||||
|
lable1->setText("请老师喝西北风");
|
||||||
|
lable2->setText("请客次数: "+QString::number(n));
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget::~Widget()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
#ifndef WIDGET_H
|
||||||
|
#define WIDGET_H
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QLabel>
|
||||||
|
#include "teacher.h"
|
||||||
|
#include "student.h"
|
||||||
|
|
||||||
|
class Widget : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
private:
|
||||||
|
Teacher *t1;
|
||||||
|
Student *s1;
|
||||||
|
int n;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QPushButton *btn,*btn2;
|
||||||
|
QLabel *lable1,*lable2;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void handleHot();
|
||||||
|
void print();
|
||||||
|
void noMoney();
|
||||||
|
|
||||||
|
public:
|
||||||
|
Widget(QWidget *parent = nullptr);
|
||||||
|
~Widget();
|
||||||
|
};
|
||||||
|
#endif // WIDGET_H
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
#include "custom.h"
|
||||||
|
|
||||||
|
Custom::Custom(QWidget *parent)
|
||||||
|
: QWidget(parent)
|
||||||
|
{
|
||||||
|
// 初始化窗口的控件
|
||||||
|
nameEdit = new QLineEdit(this);
|
||||||
|
nameEdit->resize(200,40);
|
||||||
|
nameEdit->move(10,10);
|
||||||
|
|
||||||
|
nEdit = new QLineEdit(this);
|
||||||
|
nEdit->resize(100,40);
|
||||||
|
nEdit->move(10,60);
|
||||||
|
|
||||||
|
toOrderBtn = new QPushButton("下单",this);
|
||||||
|
toOrderBtn->resize(80,40);
|
||||||
|
toOrderBtn->move(10,110);
|
||||||
|
|
||||||
|
eatStateLable = new QLabel("未开吃",this);
|
||||||
|
eatStateLable->resize(100,40);
|
||||||
|
eatStateLable->move(10,160);
|
||||||
|
|
||||||
|
// 设置按钮的点击事件的处理函数
|
||||||
|
connect(toOrderBtn,&QPushButton::clicked,this,&Custom::toOrderHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Custom::toOrderHandle()
|
||||||
|
{
|
||||||
|
eatStateLable->setText("等待上菜……");
|
||||||
|
// 下单按钮被点击了
|
||||||
|
qDebug() << "准备下单了";
|
||||||
|
qDebug() << "你的菜品: "<< nameEdit->text() << ", 数量:" << nEdit->text();
|
||||||
|
|
||||||
|
// 向店家发送信号,信号中包含菜品名和数量
|
||||||
|
emit toOrderSignal(nameEdit->text(), nEdit->text().toInt());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Custom::okOrderHandle()
|
||||||
|
{
|
||||||
|
eatStateLable->setText(nameEdit->text()+"开吃……");
|
||||||
|
}
|
||||||
|
|
||||||
|
Custom::~Custom()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
#ifndef CUSTOM_H
|
||||||
|
#define CUSTOM_H
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QLineEdit>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
class Custom : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
private:
|
||||||
|
QLineEdit *nameEdit; // 菜品
|
||||||
|
QLineEdit *nEdit; // 数量
|
||||||
|
QPushButton *toOrderBtn; // 下单
|
||||||
|
QLabel *eatStateLable; // 开吃状态
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void toOrderHandle(); // 处理按钮的点击事件
|
||||||
|
void okOrderHandle(); // 店家上菜信号的处理函数
|
||||||
|
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void toOrderSignal(QString name,int n);
|
||||||
|
|
||||||
|
public:
|
||||||
|
Custom(QWidget *parent = nullptr);
|
||||||
|
~Custom();
|
||||||
|
};
|
||||||
|
#endif // CUSTOM_H
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
#include "custom.h"
|
||||||
|
#include "restaurant.h"
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
QApplication a(argc, argv);
|
||||||
|
Custom c;
|
||||||
|
c.setWindowTitle("点餐系统");
|
||||||
|
c.resize(800,600);
|
||||||
|
|
||||||
|
// 创建店类的对象
|
||||||
|
Restaurant r;
|
||||||
|
|
||||||
|
// 绑定客户下单信号处理函数
|
||||||
|
void (Custom:: *toOrder)(QString, int) = &Custom::toOrderSignal;
|
||||||
|
void (Restaurant:: *receiveOrder)(QString, int) = &Restaurant::receiveOrder;
|
||||||
|
QObject::connect(&c,toOrder,&r,receiveOrder);
|
||||||
|
|
||||||
|
// 绑定店家上菜信号和客户的槽函数
|
||||||
|
QObject::connect(&r,&Restaurant::okOrder,&c,&Custom::okOrderHandle);
|
||||||
|
|
||||||
|
c.show();
|
||||||
|
return a.exec();
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
QT += core gui
|
||||||
|
|
||||||
|
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||||
|
|
||||||
|
CONFIG += c++11
|
||||||
|
|
||||||
|
# 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 \
|
||||||
|
custom.cpp \
|
||||||
|
restaurant.cpp
|
||||||
|
|
||||||
|
HEADERS += \
|
||||||
|
custom.h \
|
||||||
|
restaurant.h
|
||||||
|
|
||||||
|
# Default rules for deployment.
|
||||||
|
qnx: target.path = /tmp/$${TARGET}/bin
|
||||||
|
else: unix:!android: target.path = /opt/$${TARGET}/bin
|
||||||
|
!isEmpty(target.path): INSTALLS += target
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
#include "restaurant.h"
|
||||||
|
|
||||||
|
Restaurant::Restaurant(QWidget *parent) : QWidget(parent)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Restaurant::receiveOrder(QString name, int n)
|
||||||
|
{
|
||||||
|
qDebug() << "店家已接收到菜单: " << name << ", 数量: " << n;
|
||||||
|
|
||||||
|
// 等待 10 秒
|
||||||
|
// QThread::msleep(10*1000); // 单位毫秒,UI阻塞
|
||||||
|
|
||||||
|
// 创建定时器,UI非阻塞
|
||||||
|
QTimer *timer = new QTimer();
|
||||||
|
// 绑定定时器的超时信号与 Lambda 表达式的匿名处理函数
|
||||||
|
QTimer::connect(timer,&QTimer::timeout,[&](){
|
||||||
|
qDebug() << "完成订单,上菜";
|
||||||
|
// 发送上菜的信号
|
||||||
|
emit okOrder();
|
||||||
|
});
|
||||||
|
timer->setSingleShot(true); // 单次使用
|
||||||
|
timer->start(10*1000); // 单位: 毫秒
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
#ifndef RESTAURANT_H
|
||||||
|
#define RESTAURANT_H
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QTimer>
|
||||||
|
#include <QDebug>
|
||||||
|
#include "custom.h"
|
||||||
|
|
||||||
|
class Restaurant : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit Restaurant(QWidget *parent = nullptr);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
// 接单的处理槽函数
|
||||||
|
void receiveOrder(QString name, int n);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void okOrder(); // 完成菜品
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // RESTAURANT_H
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
#include "awidget.h"
|
||||||
|
|
||||||
|
aWidget::aWidget(QWidget *parent)
|
||||||
|
: QWidget(parent)
|
||||||
|
{
|
||||||
|
// 设置A窗口实例的属性
|
||||||
|
setFixedSize(400,200);
|
||||||
|
setWindowTitle("A界面");
|
||||||
|
move(200,100);
|
||||||
|
|
||||||
|
// 新建B窗口对象
|
||||||
|
b = new bWidget();
|
||||||
|
b->setFixedSize(400,200);
|
||||||
|
b->setWindowTitle("B界面");
|
||||||
|
b->move(800,100);
|
||||||
|
|
||||||
|
// 新建“进入B”按钮,并设置其属性
|
||||||
|
btnToB = new QPushButton("进入B",this);
|
||||||
|
btnToB->resize(60,40);
|
||||||
|
|
||||||
|
// 绑定“进入B”按钮点击信号与“进入B界面并隐藏A界面”的槽函数
|
||||||
|
connect(btnToB,&QPushButton::clicked,this,&aWidget::toBHandle);
|
||||||
|
// 绑定“B界面返回A界面信号”与当前界面的“A界面显示并隐藏B界面”的槽函数
|
||||||
|
connect(b,&bWidget::returnASignal,this,&aWidget::returnAHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void aWidget::toBHandle()
|
||||||
|
{
|
||||||
|
this->hide(); // 隐藏A界面
|
||||||
|
b->show(); // 显示B界面
|
||||||
|
}
|
||||||
|
|
||||||
|
void aWidget::returnAHandle()
|
||||||
|
{
|
||||||
|
b->hide(); // 隐藏B界面
|
||||||
|
this->show(); // 显示A界面
|
||||||
|
}
|
||||||
|
|
||||||
|
aWidget::~aWidget()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
#ifndef AWIDGET_H
|
||||||
|
#define AWIDGET_H
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QDebug>
|
||||||
|
#include "bwidget.h"
|
||||||
|
|
||||||
|
class aWidget : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
private:
|
||||||
|
bWidget *b;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void toBHandle();
|
||||||
|
void returnAHandle();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void toBSignal();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QPushButton *btnToB;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
aWidget(QWidget *parent = nullptr);
|
||||||
|
~aWidget();
|
||||||
|
};
|
||||||
|
#endif // AWIDGET_H
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
#include "bwidget.h"
|
||||||
|
|
||||||
|
bWidget::bWidget(QWidget *parent) : QWidget(parent)
|
||||||
|
{
|
||||||
|
// 新建“返回A”按钮,并设置其属性
|
||||||
|
btnReturnA = new QPushButton("返回A",this);
|
||||||
|
btnReturnA->resize(60,40);
|
||||||
|
|
||||||
|
// 绑定“返回A”按钮点击事件与“发送返回A界面的信号”的槽函数
|
||||||
|
connect(btnReturnA,&QPushButton::clicked,this,&bWidget::sendReturnASignal);
|
||||||
|
}
|
||||||
|
|
||||||
|
void bWidget::sendReturnASignal()
|
||||||
|
{
|
||||||
|
emit returnASignal(); // 触发“返回A界面”信号
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
#ifndef BWIDGET_H
|
||||||
|
#define BWIDGET_H
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
class bWidget : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
private:
|
||||||
|
QPushButton *btnReturnA;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void sendReturnASignal();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void returnASignal();
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit bWidget(QWidget *parent = nullptr);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // BWIDGET_H
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
#include "awidget.h"
|
||||||
|
#include "bwidget.h"
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
QApplication qa(argc, argv);
|
||||||
|
aWidget a; // 新建一个界面A对象a
|
||||||
|
a.show(); // 程序初始化运行时显示A对象a界面
|
||||||
|
return qa.exec();
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
QT += core gui
|
||||||
|
|
||||||
|
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||||
|
|
||||||
|
CONFIG += c++11
|
||||||
|
|
||||||
|
# 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 += \
|
||||||
|
bwidget.cpp \
|
||||||
|
main.cpp \
|
||||||
|
awidget.cpp
|
||||||
|
|
||||||
|
HEADERS += \
|
||||||
|
awidget.h \
|
||||||
|
bwidget.h
|
||||||
|
|
||||||
|
# Default rules for deployment.
|
||||||
|
qnx: target.path = /tmp/$${TARGET}/bin
|
||||||
|
else: unix:!android: target.path = /opt/$${TARGET}/bin
|
||||||
|
!isEmpty(target.path): INSTALLS += target
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
#include "widget.h"
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
QApplication a(argc, argv);
|
||||||
|
Widget w;
|
||||||
|
w.show();
|
||||||
|
return a.exec();
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
QT += core gui
|
||||||
|
|
||||||
|
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||||
|
|
||||||
|
CONFIG += c++11
|
||||||
|
|
||||||
|
# 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 \
|
||||||
|
widget.cpp
|
||||||
|
|
||||||
|
HEADERS += \
|
||||||
|
widget.h
|
||||||
|
|
||||||
|
FORMS += \
|
||||||
|
widget.ui
|
||||||
|
|
||||||
|
# Default rules for deployment.
|
||||||
|
qnx: target.path = /tmp/$${TARGET}/bin
|
||||||
|
else: unix:!android: target.path = /opt/$${TARGET}/bin
|
||||||
|
!isEmpty(target.path): INSTALLS += target
|
||||||
|
|
||||||
|
RESOURCES += \
|
||||||
|
res.qrc
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
<RCC>
|
||||||
|
<qresource prefix="/images">
|
||||||
|
<file alias="add">resources/add.png</file>
|
||||||
|
<file alias="mario">resources/mario.gif</file>
|
||||||
|
<file alias="open">resources/open.png</file>
|
||||||
|
<file alias="save">resources/save.png</file>
|
||||||
|
<file alias="sunny">resources/Sunny.jpg</file>
|
||||||
|
</qresource>
|
||||||
|
<qresource prefix="/videos"/>
|
||||||
|
</RCC>
|
||||||
|
After Width: | Height: | Size: 36 KiB |
|
After Width: | Height: | Size: 8.9 KiB |
|
After Width: | Height: | Size: 1.4 MiB |
|
After Width: | Height: | Size: 8.7 KiB |
|
After Width: | Height: | Size: 11 KiB |
@@ -0,0 +1,99 @@
|
|||||||
|
#include "widget.h"
|
||||||
|
#include "ui_widget.h"
|
||||||
|
#include <QPixmap>
|
||||||
|
|
||||||
|
|
||||||
|
Widget::Widget(QWidget *parent)
|
||||||
|
: QWidget(parent)
|
||||||
|
, ui(new Ui::Widget)
|
||||||
|
{
|
||||||
|
n=0;
|
||||||
|
ui->setupUi(this);
|
||||||
|
|
||||||
|
// 设置 imageLable 的图片资源
|
||||||
|
QPixmap pixmap;
|
||||||
|
// : 开头表示引用 Qt 的资源文件
|
||||||
|
pixmap.load(":/images/mario"); // 加载像素图
|
||||||
|
ui->imageLable->resize(200,200);
|
||||||
|
ui->imageLable->setPixmap(pixmap); // 设置 QLable 显示图片
|
||||||
|
|
||||||
|
marioGif = new QMovie(":/images/mario");
|
||||||
|
ui->imageLable->setMovie(marioGif);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget::~Widget()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Widget::on_hotBtn_clicked()
|
||||||
|
{
|
||||||
|
ui->whatLable->setText("巧乐兹");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Widget::on_coldBtn_clicked()
|
||||||
|
{
|
||||||
|
ui->whatLable->setText("厚棉被");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Widget::on_coldBtn_2_clicked()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Widget::on_setTitleIconBtn_clicked()
|
||||||
|
{
|
||||||
|
n++;
|
||||||
|
if(n%2==0){
|
||||||
|
|
||||||
|
this->setWindowIcon(QIcon(":/images/save"));
|
||||||
|
this->setWindowTitle("标题被修改了");
|
||||||
|
showMaximized();
|
||||||
|
} else{
|
||||||
|
this->setWindowIcon(QIcon(""));
|
||||||
|
this->setWindowTitle("");
|
||||||
|
showNormal();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Widget::on_showImg_pressed()
|
||||||
|
{
|
||||||
|
//ui->imageLable->hide();
|
||||||
|
marioGif->start();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Widget::on_showImg_released()
|
||||||
|
{
|
||||||
|
marioGif->stop();
|
||||||
|
//ui->imageLable->show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Widget::on_setImgBtn_pressed()
|
||||||
|
{
|
||||||
|
QPixmap pixmap2;
|
||||||
|
pixmap2.load(":/images/sunny");
|
||||||
|
|
||||||
|
ui->showImg->setText("");
|
||||||
|
ui->showImg->setIconSize(QSize(200,200));
|
||||||
|
ui->showImg->setIcon(pixmap2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Widget::on_setImgBtn_released()
|
||||||
|
{
|
||||||
|
ui->showImg->setText("图片运输中");
|
||||||
|
ui->showImg->setIcon(QPixmap());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Widget::on_setbgBtn_clicked()
|
||||||
|
{
|
||||||
|
// setStyleSheet("background-color: red; color: white; font-size: 16px;");
|
||||||
|
//setStyleSheet("background: qlineargradient(x1:0, y1:0, x2:1, y2:0, stop:0 #FF0000, stop:0.17 #FF7F00, stop:0.33 #FFFF00, stop:0.5 #00FF00, stop:0.67 #0000FF, stop:0.83 #4B0082, stop:1 #8B00FF);");
|
||||||
|
//QString styleSheet = "background: qlineargradient(x1:0, y1:0, x2:1, y2:0, stop:0.5 #000000, stop:0 #FF00F0,stop:1 #0F0F0F);";
|
||||||
|
//setStyleSheet(styleSheet);
|
||||||
|
showFullScreen();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
#ifndef WIDGET_H
|
||||||
|
#define WIDGET_H
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QMovie>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
namespace Ui { class Widget; }
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
class Widget : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
private:
|
||||||
|
int n;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Widget(QWidget *parent = nullptr);
|
||||||
|
~Widget();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void on_hotBtn_clicked();
|
||||||
|
|
||||||
|
void on_coldBtn_clicked();
|
||||||
|
|
||||||
|
void on_coldBtn_2_clicked();
|
||||||
|
|
||||||
|
void on_setTitleIconBtn_clicked();
|
||||||
|
|
||||||
|
void on_setImgBtn_clicked();
|
||||||
|
|
||||||
|
void on_showImg_pressed();
|
||||||
|
|
||||||
|
void on_showImg_released();
|
||||||
|
|
||||||
|
void on_setImgBtn_pressed();
|
||||||
|
|
||||||
|
void on_setImgBtn_released();
|
||||||
|
|
||||||
|
void on_setbgBtn_clicked(bool checked);
|
||||||
|
|
||||||
|
void on_setbgBtn_clicked();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::Widget *ui;
|
||||||
|
QMovie *marioGif;
|
||||||
|
};
|
||||||
|
#endif // WIDGET_H
|
||||||
@@ -0,0 +1,216 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>Widget</class>
|
||||||
|
<widget class="QWidget" name="Widget">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>654</width>
|
||||||
|
<height>476</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="cursor">
|
||||||
|
<cursorShape>OpenHandCursor</cursorShape>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Widget</string>
|
||||||
|
</property>
|
||||||
|
<property name="windowIcon">
|
||||||
|
<iconset resource="res.qrc">
|
||||||
|
<normaloff>:/images/open</normaloff>:/images/open</iconset>
|
||||||
|
</property>
|
||||||
|
<widget class="QPushButton" name="hotBtn">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>170</x>
|
||||||
|
<y>8</y>
|
||||||
|
<width>201</width>
|
||||||
|
<height>81</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="cursor">
|
||||||
|
<cursorShape>ClosedHandCursor</cursorShape>
|
||||||
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">font: 36pt "华文隶书";
|
||||||
|
alternate-background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(9, 41, 4, 255), stop:0.085 rgba(2, 79, 0, 255), stop:0.19 rgba(50, 147, 22, 255), stop:0.275 rgba(236, 191, 49, 255), stop:0.39 rgba(243, 61, 34, 255), stop:0.555 rgba(135, 81, 60, 255), stop:0.667 rgba(121, 75, 255, 255), stop:0.825 rgba(164, 255, 244, 255), stop:0.885 rgba(104, 222, 71, 255), stop:1 rgba(93, 128, 0, 255));
|
||||||
|
color: rgb(255, 85, 255);</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>热了</string>
|
||||||
|
</property>
|
||||||
|
<property name="iconSize">
|
||||||
|
<size>
|
||||||
|
<width>37</width>
|
||||||
|
<height>55</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>10</x>
|
||||||
|
<y>110</y>
|
||||||
|
<width>191</width>
|
||||||
|
<height>69</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="cursor">
|
||||||
|
<cursorShape>WhatsThisCursor</cursorShape>
|
||||||
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">background-color: rgb(0, 170, 255);
|
||||||
|
font: 18pt "华文琥珀";</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>出门买啥?</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QLabel" name="whatLable">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>230</x>
|
||||||
|
<y>120</y>
|
||||||
|
<width>361</width>
|
||||||
|
<height>141</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="cursor">
|
||||||
|
<cursorShape>SizeBDiagCursor</cursorShape>
|
||||||
|
</property>
|
||||||
|
<property name="layoutDirection">
|
||||||
|
<enum>Qt::RightToLeft</enum>
|
||||||
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">background-color: rgb(255, 85, 0);
|
||||||
|
color: rgb(255, 255, 255);
|
||||||
|
background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(255, 0, 0, 255), stop:0.166 rgba(255, 255, 0, 255), stop:0.333 rgba(0, 255, 0, 255), stop:0.5 rgba(0, 255, 255, 255), stop:0.666 rgba(0, 0, 255, 255), stop:0.833 rgba(255, 0, 255, 255), stop:1 rgba(255, 0, 0, 255));
|
||||||
|
font: 72pt "华文彩云";</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QPushButton" name="coldBtn">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>410</x>
|
||||||
|
<y>10</y>
|
||||||
|
<width>201</width>
|
||||||
|
<height>81</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="cursor">
|
||||||
|
<cursorShape>CrossCursor</cursorShape>
|
||||||
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">font: 36pt "华文隶书";
|
||||||
|
selection-background-color: rgb(255, 170, 127);
|
||||||
|
color: rgb(170, 255, 255);</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>冻着了</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QLabel" name="imageLable">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>20</x>
|
||||||
|
<y>260</y>
|
||||||
|
<width>121</width>
|
||||||
|
<height>121</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="cursor">
|
||||||
|
<cursorShape>WaitCursor</cursorShape>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QPushButton" name="setImgBtn">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>240</x>
|
||||||
|
<y>300</y>
|
||||||
|
<width>191</width>
|
||||||
|
<height>49</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="cursor">
|
||||||
|
<cursorShape>SizeHorCursor</cursorShape>
|
||||||
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">font: 28pt "华文隶书";
|
||||||
|
</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>设置图片</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QPushButton" name="setTitleIconBtn">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>240</x>
|
||||||
|
<y>400</y>
|
||||||
|
<width>191</width>
|
||||||
|
<height>49</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="cursor">
|
||||||
|
<cursorShape>UpArrowCursor</cursorShape>
|
||||||
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">font: 18pt "华文隶书";
|
||||||
|
</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>标题Icon修改</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QPushButton" name="showImg">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>440</x>
|
||||||
|
<y>280</y>
|
||||||
|
<width>201</width>
|
||||||
|
<height>181</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="cursor">
|
||||||
|
<cursorShape>ForbiddenCursor</cursorShape>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>图片正在派送中</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QPushButton" name="setbgBtn">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>20</x>
|
||||||
|
<y>40</y>
|
||||||
|
<width>141</width>
|
||||||
|
<height>49</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="cursor">
|
||||||
|
<cursorShape>UpArrowCursor</cursorShape>
|
||||||
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">font: 18pt "华文隶书";
|
||||||
|
</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>背景修改</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
<resources>
|
||||||
|
<include location="res.qrc"/>
|
||||||
|
</resources>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
#include "widget.h"
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
QApplication a(argc, argv);
|
||||||
|
Widget w;
|
||||||
|
w.show();
|
||||||
|
return a.exec();
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
QT += core gui
|
||||||
|
|
||||||
|
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||||
|
|
||||||
|
CONFIG += c++11
|
||||||
|
|
||||||
|
# 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 \
|
||||||
|
widget.cpp
|
||||||
|
|
||||||
|
HEADERS += \
|
||||||
|
widget.h
|
||||||
|
|
||||||
|
FORMS += \
|
||||||
|
widget.ui
|
||||||
|
|
||||||
|
# Default rules for deployment.
|
||||||
|
qnx: target.path = /tmp/$${TARGET}/bin
|
||||||
|
else: unix:!android: target.path = /opt/$${TARGET}/bin
|
||||||
|
!isEmpty(target.path): INSTALLS += target
|
||||||
|
|
||||||
|
RESOURCES += \
|
||||||
|
res.qrc
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
<RCC>
|
||||||
|
<qresource prefix="/movies">
|
||||||
|
<file alias="yanhua">resources/yanhua1.gif</file>
|
||||||
|
</qresource>
|
||||||
|
</RCC>
|
||||||
|
After Width: | Height: | Size: 1.1 MiB |
@@ -0,0 +1,47 @@
|
|||||||
|
#include "widget.h"
|
||||||
|
#include "ui_widget.h"
|
||||||
|
|
||||||
|
|
||||||
|
Widget::Widget(QWidget *parent)
|
||||||
|
: QWidget(parent)
|
||||||
|
, ui(new Ui::Widget)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
|
||||||
|
// 加载动画资源
|
||||||
|
yanhuagif = new QMovie(":/movies/yanhua");
|
||||||
|
|
||||||
|
srand(time(NULL));
|
||||||
|
randNum = rand() % 10; // 0-9的数
|
||||||
|
|
||||||
|
// 开启定时器, 用于定时换随机数
|
||||||
|
timer = new QTimer();
|
||||||
|
connect(timer,&QTimer::timeout,[&](){
|
||||||
|
randNum = rand() % 10;
|
||||||
|
});
|
||||||
|
timer->start(5*1000); // 5秒
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget::~Widget()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Widget::on_pushButton_clicked()
|
||||||
|
{
|
||||||
|
guessNum = ui->numEdit->text().toInt();
|
||||||
|
qDebug() << "随机数:" << randNum << "输入的数" << guessNum << endl;
|
||||||
|
QString resStr = "随机数: "+ QString::number(randNum)+ ", 你输入的数: "+QString::number(guessNum);
|
||||||
|
ui->tipesLable->setText("本轮结果: " + resStr);
|
||||||
|
if(guessNum == randNum){
|
||||||
|
ui->resaultShowLabel->setMovie(yanhuagif);
|
||||||
|
yanhuagif->start();
|
||||||
|
} else {
|
||||||
|
if(yanhuagif->state() == QMovie::Running)
|
||||||
|
yanhuagif->stop();
|
||||||
|
ui->resaultShowLabel->setText(" ");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
#ifndef WIDGET_H
|
||||||
|
#define WIDGET_H
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QMovie>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QTimer>
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
namespace Ui { class Widget; }
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
class Widget : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
Widget(QWidget *parent = nullptr);
|
||||||
|
~Widget();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void on_pushButton_clicked();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::Widget *ui;
|
||||||
|
int guessNum = 0;
|
||||||
|
int randNum = 0;
|
||||||
|
QMovie *yanhuagif;
|
||||||
|
QTimer *timer;
|
||||||
|
};
|
||||||
|
#endif // WIDGET_H
|
||||||
@@ -0,0 +1,133 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>Widget</class>
|
||||||
|
<widget class="QWidget" name="Widget">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>500</width>
|
||||||
|
<height>400</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Widget</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="numEdit">
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">padding:5px;
|
||||||
|
font: 18pt "Agency FB";</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_2">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="pushButton">
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">font: 18pt "Agency FB";</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>猜一猜</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_3">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="Line" name="line">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QWidget" name="widget" native="true">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="tipesLable">
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">font: 14pt "宋体";
|
||||||
|
color: rgb(170, 170, 255);</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>结果: </string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="resaultShowLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
#include "mainwidget.h"
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
QApplication a(argc, argv);
|
||||||
|
MainWidget mainWidget;
|
||||||
|
|
||||||
|
mainWidget.setWindowTitle("猜拳");
|
||||||
|
mainWidget.setWindowIcon(QIcon(":/imgs/rock"));
|
||||||
|
|
||||||
|
mainWidget.show();
|
||||||
|
return a.exec();
|
||||||
|
}
|
||||||
@@ -0,0 +1,159 @@
|
|||||||
|
#include "mainwidget.h"
|
||||||
|
#include "ui_mainwidget.h"
|
||||||
|
|
||||||
|
MainWidget::MainWidget(QWidget *parent)
|
||||||
|
: QWidget(parent)
|
||||||
|
, ui(new Ui::MainWidget)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
|
||||||
|
rockImg = new QPixmap(":/imgs/rock"); // 随机数为 0 时, 加载拳头
|
||||||
|
paperImg = new QPixmap(":/imgs/paper"); // 随机数为 1 时, 加载布
|
||||||
|
scissorsImg = new QPixmap(":/imgs/scissors"); // 随机数为 2 时, 加载剪刀
|
||||||
|
|
||||||
|
// 电脑初始化时加载的图片
|
||||||
|
QPixmap firstImg;
|
||||||
|
firstImg.load(":/imgs/scissors");
|
||||||
|
ui->randImgsLable->setPixmap(firstImg);
|
||||||
|
|
||||||
|
// 初始化计分板数据
|
||||||
|
numsOfGame = 0;
|
||||||
|
currentScore = 0;
|
||||||
|
|
||||||
|
// 随机函数定义
|
||||||
|
srand(time(NULL)); // 随时间变化的随机种子
|
||||||
|
timer = new QTimer();
|
||||||
|
connect(timer,&QTimer::timeout,[&](){
|
||||||
|
randNum = rand() % 3; // 在 0-2 之间随机取值
|
||||||
|
QPixmap nowImg = switchImgs(randNum); // 根据当前的随机值加载图片
|
||||||
|
ui->randImgsLable->setPixmap(nowImg); // 将当前随机值对应的图片设置到主界面
|
||||||
|
|
||||||
|
// 调试信息
|
||||||
|
qDebug() << "numsOfGame: " << numsOfGame <<", randNum: "<<randNum
|
||||||
|
<<", playerInputNum: "<<playerInputNum<<endl;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
MainWidget::~MainWidget()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MainWidget::on_startGameBtn_clicked()
|
||||||
|
{
|
||||||
|
numsOfGame++;
|
||||||
|
|
||||||
|
timer->start(0.05*1000); // 50ms
|
||||||
|
|
||||||
|
// 更新游戏次数
|
||||||
|
ui->numsOfGameLable->setText("游戏次数: " + QString::number(numsOfGame));
|
||||||
|
}
|
||||||
|
|
||||||
|
QPixmap MainWidget::switchImgs(int randNum)
|
||||||
|
{
|
||||||
|
switch (randNum) {
|
||||||
|
case rock:
|
||||||
|
return *rockImg; // 随机数为 0 时, 加载拳头
|
||||||
|
break;
|
||||||
|
case paper:
|
||||||
|
return *paperImg; // 随机数为 1 时, 加载布
|
||||||
|
break;
|
||||||
|
case scissors:
|
||||||
|
return *scissorsImg; // 随机数为 2 时, 加载剪刀
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return *paperImg; // 默认加载布
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWidget::on_rockBtn_clicked()
|
||||||
|
{
|
||||||
|
// 当计数器状态为 false, 即计时器当前已经是 stop 状态时, 点击当前按钮时, 直接返回, 不进行其他逻辑操作
|
||||||
|
if(timer->isActive() == false){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
timer->stop(); // 随机数生成的计数器停止
|
||||||
|
playerInputNum = rock; // 玩家出拳
|
||||||
|
// 则玩家赢加 10 分, 输减 3 分, 平局不得分
|
||||||
|
if(randNum == scissors){
|
||||||
|
currentScore+=10;
|
||||||
|
} else if(randNum == paper) {
|
||||||
|
currentScore-=3;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 调试信息
|
||||||
|
qDebug() << "numsOfGame: " << numsOfGame <<", randNum: "<<randNum
|
||||||
|
<<", playerInputNum: "<<playerInputNum<<endl;
|
||||||
|
|
||||||
|
// 更新计分板
|
||||||
|
ui->currentScoreLable->setText("当前得分: " + QString::number(currentScore));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWidget::on_paperBtn_clicked()
|
||||||
|
{
|
||||||
|
// 当计数器状态为 false, 即计时器当前已经是 stop 状态时, 点击当前按钮时, 直接返回, 不进行其他逻辑操作
|
||||||
|
if(timer->isActive() == false){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
timer->stop(); // 随机数生成的计数器停止
|
||||||
|
playerInputNum = paper; // 玩家出布
|
||||||
|
// 则玩家赢加 10 分, 输减 3 分, 平局不得分
|
||||||
|
if(randNum == rock){
|
||||||
|
currentScore+=10;
|
||||||
|
} else if(randNum == scissors) {
|
||||||
|
currentScore-=3;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 调试信息
|
||||||
|
qDebug() << "numsOfGame: " << numsOfGame <<", randNum: "<<randNum
|
||||||
|
<<", playerInputNum: "<<playerInputNum<<endl;
|
||||||
|
|
||||||
|
// 更新计分板
|
||||||
|
ui->currentScoreLable->setText("当前得分: " + QString::number(currentScore));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWidget::on_scissorsBtn_clicked()
|
||||||
|
{
|
||||||
|
// 当计数器状态为 false, 即计时器当前已经是 stop 状态时, 点击当前按钮时, 直接返回, 不进行其他逻辑操作
|
||||||
|
if(timer->isActive() == false){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
timer->stop(); // 随机数生成的计数器停止
|
||||||
|
playerInputNum = scissors; // 玩家出剪刀
|
||||||
|
// 则玩家赢加 10 分, 输减 3 分, 平局不得分
|
||||||
|
if(randNum == paper){
|
||||||
|
currentScore+=10;
|
||||||
|
} else if(randNum == rock) {
|
||||||
|
currentScore-=3;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 调试信息
|
||||||
|
qDebug() << "numsOfGame: " << numsOfGame <<", randNum: "<<randNum
|
||||||
|
<<", playerInputNum: "<<playerInputNum<<endl;
|
||||||
|
|
||||||
|
// 更新计分板
|
||||||
|
ui->currentScoreLable->setText("当前得分: " + QString::number(currentScore));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWidget::on_clearBtn_clicked()
|
||||||
|
{
|
||||||
|
timer->stop(); // 随机数生成的计数器停止
|
||||||
|
|
||||||
|
// 统计数据重置为 0
|
||||||
|
currentScore = 0;
|
||||||
|
numsOfGame = 0;
|
||||||
|
|
||||||
|
// 更新游戏次数
|
||||||
|
ui->numsOfGameLable->setText("游戏次数: ");
|
||||||
|
// 更新计分板
|
||||||
|
ui->currentScoreLable->setText("当前得分: ");
|
||||||
|
|
||||||
|
// 调试信息
|
||||||
|
qDebug() << "numsOfGame: " << numsOfGame <<", randNum: "<<randNum
|
||||||
|
<<", playerInputNum: "<<playerInputNum<<endl;
|
||||||
|
}
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
#ifndef MAINWIDGET_H
|
||||||
|
#define MAINWIDGET_H
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QIcon>
|
||||||
|
#include <QPixmap>
|
||||||
|
#include <QTimer>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
namespace Ui { class MainWidget; }
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
class MainWidget : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
MainWidget(QWidget *parent = nullptr);
|
||||||
|
~MainWidget();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::MainWidget *ui;
|
||||||
|
QPixmap switchImgs(int); // 切换电脑图片函数
|
||||||
|
|
||||||
|
private:
|
||||||
|
int randNum; // 电脑出招映射的随机数 0, 1, 2
|
||||||
|
int playerInputNum; // 玩家点击的按钮映射的数值 0, 1, 2
|
||||||
|
QTimer *timer; // 计时器
|
||||||
|
// QPixmap *randImg; // 随机的电脑出招图片
|
||||||
|
int numsOfGame; // 游戏次数
|
||||||
|
int currentScore; // 当前得分
|
||||||
|
QPixmap *rockImg; // 拳头
|
||||||
|
QPixmap *paperImg; // 布
|
||||||
|
QPixmap *scissorsImg; // 剪刀
|
||||||
|
|
||||||
|
public:
|
||||||
|
// 定义枚举: 0-拳、1-布、2-剪刀
|
||||||
|
enum{
|
||||||
|
rock,
|
||||||
|
paper,
|
||||||
|
scissors
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void on_startGameBtn_clicked();
|
||||||
|
void on_rockBtn_clicked();
|
||||||
|
void on_paperBtn_clicked();
|
||||||
|
void on_scissorsBtn_clicked();
|
||||||
|
void on_clearBtn_clicked();
|
||||||
|
};
|
||||||
|
#endif // MAINWIDGET_H
|
||||||
@@ -0,0 +1,431 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>MainWidget</class>
|
||||||
|
<widget class="QWidget" name="MainWidget">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>800</width>
|
||||||
|
<height>600</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>MainWidget</string>
|
||||||
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">background-color: qconicalgradient(cx:0, cy:0, angle:135, stop:0 rgba(255, 255, 0, 69), stop:0.375 rgba(255, 255, 0, 69), stop:0.423533 rgba(251, 255, 0, 145), stop:0.45 rgba(247, 255, 0, 208), stop:0.477581 rgba(255, 244, 71, 130), stop:0.518717 rgba(255, 218, 71, 130), stop:0.55 rgba(255, 255, 0, 255), stop:0.57754 rgba(255, 203, 0, 130), stop:0.625 rgba(255, 255, 0, 69), stop:1 rgba(255, 255, 0, 69));</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QWidget" name="widget" native="true">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QWidget" name="widget_3" native="true">
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>500</width>
|
||||||
|
<height>500</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">background-color: rgb(0, 170, 255);</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout_2">
|
||||||
|
<item row="0" column="1">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_7">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_11">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_13">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="randImgsLable">
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>500</width>
|
||||||
|
<height>500</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="baseSize">
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="autoFillBackground">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="scaledContents">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_14">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_12">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_10">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="2">
|
||||||
|
<widget class="Line" name="line_2">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_9">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QWidget" name="widget_4" native="true">
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">background-color: rgb(255, 85, 0);</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="rockBtn">
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>130</width>
|
||||||
|
<height>130</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="res.qrc">
|
||||||
|
<normaloff>:/imgs/rock</normaloff>:/imgs/rock</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="iconSize">
|
||||||
|
<size>
|
||||||
|
<width>130</width>
|
||||||
|
<height>130</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="paperBtn">
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>130</width>
|
||||||
|
<height>130</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="res.qrc">
|
||||||
|
<normaloff>:/imgs/paper</normaloff>:/imgs/paper</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="iconSize">
|
||||||
|
<size>
|
||||||
|
<width>130</width>
|
||||||
|
<height>130</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer_2">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="scissorsBtn">
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>130</width>
|
||||||
|
<height>130</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="res.qrc">
|
||||||
|
<normaloff>:/imgs/scissors</normaloff>:/imgs/scissors</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="iconSize">
|
||||||
|
<size>
|
||||||
|
<width>130</width>
|
||||||
|
<height>130</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_8">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="Line" name="line">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QWidget" name="widget_2" native="true">
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">background-color: rgb(85, 255, 255);</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_3">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="numsOfGameLable">
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">font: 18pt "黑体";</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>游戏次数: </string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_5">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="currentScoreLable">
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">font: 18pt "黑体";</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>当前得分: </string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_2">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_4">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="startGameBtn">
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">font: 18pt "黑体";
|
||||||
|
color: rgb(255, 0, 0);</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>开始游戏</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="clearBtn">
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">font: 18pt "黑体";
|
||||||
|
color: rgb(255, 0, 0);</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>清零</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_6">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources>
|
||||||
|
<include location="res.qrc"/>
|
||||||
|
</resources>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
<RCC>
|
||||||
|
<qresource prefix="/imgs">
|
||||||
|
<file alias="paper">resources/paper.png</file>
|
||||||
|
<file alias="rock">resources/rock.png</file>
|
||||||
|
<file alias="scissors">resources/scissors.png</file>
|
||||||
|
</qresource>
|
||||||
|
</RCC>
|
||||||
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 20 KiB |
@@ -0,0 +1,34 @@
|
|||||||
|
QT += core gui
|
||||||
|
|
||||||
|
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||||
|
|
||||||
|
CONFIG += c++11
|
||||||
|
|
||||||
|
# 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 \
|
||||||
|
mainwidget.cpp
|
||||||
|
|
||||||
|
HEADERS += \
|
||||||
|
mainwidget.h
|
||||||
|
|
||||||
|
FORMS += \
|
||||||
|
mainwidget.ui
|
||||||
|
|
||||||
|
# Default rules for deployment.
|
||||||
|
qnx: target.path = /tmp/$${TARGET}/bin
|
||||||
|
else: unix:!android: target.path = /opt/$${TARGET}/bin
|
||||||
|
!isEmpty(target.path): INSTALLS += target
|
||||||
|
|
||||||
|
RESOURCES += \
|
||||||
|
res.qrc
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
cc = g++
|
||||||
|
cflags = -Wall -lssl -lcrypto -lcurl -ljsoncpp
|
||||||
|
cflags += -I/home/flykhan/.tools/openssl_build/include/
|
||||||
|
cflags += -I/home/flykhan/.tools/curl/include/
|
||||||
|
cflags += -I/home/flykhan/.tools/jsoncpp-Sandbox/jsoncpp-build/include/
|
||||||
|
cflags += -L/home/flykhan/.tools/openssl_build/lib/
|
||||||
|
cflags += -L/home/flykhan/.tools/curl/lib/
|
||||||
|
cflags += -L/home/flykhan/.tools/jsoncpp-Sandbox/jsoncpp-build/lib/
|
||||||
|
|
||||||
|
main: main.cpp
|
||||||
|
$(cc) main.cpp -o main $(cflags) -std=c++14
|
||||||
|
clean:
|
||||||
|
rm *.o main -rf
|
||||||
|
After Width: | Height: | Size: 502 KiB |
@@ -0,0 +1,264 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2017 Baidu.com, Inc. All Rights Reserved
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||||
|
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations under the License.
|
||||||
|
*
|
||||||
|
* @author baidu aip
|
||||||
|
*/
|
||||||
|
#ifndef __AIP_BASE_H__
|
||||||
|
#define __AIP_BASE_H__
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <cstring>
|
||||||
|
#include "http.h"
|
||||||
|
#include "json/json.h"
|
||||||
|
#include "base64.h"
|
||||||
|
#include "curl/curl.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
namespace aip {
|
||||||
|
|
||||||
|
static const char* AIP_SDK_VERSION = "0.3.3";
|
||||||
|
static const char* CURL_ERROR_CODE = "curl_error_code";
|
||||||
|
static const std::string ACCESS_TOKEN_URL = "https://aip.baidubce.com/oauth/2.0/token";
|
||||||
|
static const std::map<std::string, std::string> null;
|
||||||
|
|
||||||
|
class AipBase
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
std::string _app_id;
|
||||||
|
int _expired_time;
|
||||||
|
bool _is_bce;
|
||||||
|
bool _has_decide_type;
|
||||||
|
std::string _scope;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::string getAccessToken()
|
||||||
|
{
|
||||||
|
time_t now = time(NULL);
|
||||||
|
if (!access_token.empty())
|
||||||
|
{
|
||||||
|
return this->access_token;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (now < this->_expired_time - 60 * 60 * 24)
|
||||||
|
{
|
||||||
|
return this->access_token;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string response;
|
||||||
|
std::map<std::string, std::string> params;
|
||||||
|
|
||||||
|
params["grant_type"] = "client_credentials";
|
||||||
|
params["client_id"] = this->ak;
|
||||||
|
params["client_secret"] = this->sk;
|
||||||
|
int status_code = this->client.get(
|
||||||
|
ACCESS_TOKEN_URL,
|
||||||
|
¶ms,
|
||||||
|
nullptr,
|
||||||
|
&response
|
||||||
|
);
|
||||||
|
Json::Value obj;
|
||||||
|
if (status_code != CURLcode::CURLE_OK) {
|
||||||
|
obj[CURL_ERROR_CODE] = status_code;
|
||||||
|
return obj.toStyledString();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string error;
|
||||||
|
std::unique_ptr<Json::CharReader> reader(crbuilder.newCharReader());
|
||||||
|
reader->parse(response.data(), response.data() + response.size(), &obj, &error);
|
||||||
|
this->access_token = obj["access_token"].asString();
|
||||||
|
this->_expired_time = obj["expires_in"].asInt() + (int) now;
|
||||||
|
this->_scope = obj["scope"].asString();
|
||||||
|
return this->access_token;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
std::string ak;
|
||||||
|
std::string sk;
|
||||||
|
HttpClient client;
|
||||||
|
Json::CharReaderBuilder crbuilder;
|
||||||
|
std::string access_token;
|
||||||
|
AipBase(const std::string & app_id, const std::string & ak, const std::string & sk):
|
||||||
|
_app_id(app_id),
|
||||||
|
_is_bce(false),
|
||||||
|
_has_decide_type(false),
|
||||||
|
ak(ak),
|
||||||
|
sk(sk)
|
||||||
|
{
|
||||||
|
if (_app_id == "")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setConnectionTimeoutInMillis(int connect_timeout)
|
||||||
|
{
|
||||||
|
this->client.setConnectTimeout(connect_timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setSocketTimeoutInMillis(int socket_timeout)
|
||||||
|
{
|
||||||
|
this->client.setSocketTimeout(socket_timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setDebug(bool debug)
|
||||||
|
{
|
||||||
|
this->client.setDebug(debug);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string getAk() {
|
||||||
|
return ak;
|
||||||
|
}
|
||||||
|
|
||||||
|
Json::Value request(
|
||||||
|
std::string url,
|
||||||
|
std::map<std::string, std::string> const & params,
|
||||||
|
std::string const & data,
|
||||||
|
std::map<std::string, std::string> const & headers)
|
||||||
|
{
|
||||||
|
std::string response;
|
||||||
|
Json::Value obj;
|
||||||
|
std::string body;
|
||||||
|
auto headers_for_sign = headers;
|
||||||
|
|
||||||
|
auto temp_params = params;
|
||||||
|
|
||||||
|
temp_params["charset"] = "UTF-8";
|
||||||
|
|
||||||
|
this->prepare_request(url, temp_params, headers_for_sign);
|
||||||
|
|
||||||
|
int status_code = this->client.post(url, &temp_params, data, &headers_for_sign, &response);
|
||||||
|
|
||||||
|
if (status_code != CURLcode::CURLE_OK) {
|
||||||
|
obj[CURL_ERROR_CODE] = status_code;
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string error;
|
||||||
|
std::unique_ptr<Json::CharReader> reader(crbuilder.newCharReader());
|
||||||
|
reader->parse(response.data(), response.data() + response.size(), &obj, &error);
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
Json::Value request(
|
||||||
|
std::string url,
|
||||||
|
std::map<std::string, std::string> const & params,
|
||||||
|
std::map<std::string, std::string> const & data,
|
||||||
|
std::map<std::string, std::string> const & headers)
|
||||||
|
{
|
||||||
|
std::string response;
|
||||||
|
Json::Value obj;
|
||||||
|
|
||||||
|
auto headers_for_sign = headers;
|
||||||
|
auto temp_params = params;
|
||||||
|
|
||||||
|
this->prepare_request(url, temp_params, headers_for_sign);
|
||||||
|
|
||||||
|
int status_code = this->client.post(url, &temp_params, data, &headers_for_sign, &response);
|
||||||
|
|
||||||
|
if (status_code != CURLcode::CURLE_OK) {
|
||||||
|
obj[CURL_ERROR_CODE] = status_code;
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string error;
|
||||||
|
std::unique_ptr<Json::CharReader> reader(crbuilder.newCharReader());
|
||||||
|
reader->parse(response.data(), response.data() + response.size(), &obj, &error);
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
void prepare_request(std::string url,
|
||||||
|
std::map<std::string, std::string> & params,
|
||||||
|
std::map<std::string, std::string> & headers)
|
||||||
|
{
|
||||||
|
|
||||||
|
params["aipSdk"] = "C";
|
||||||
|
params["aipSdkVersion"] = AIP_SDK_VERSION;
|
||||||
|
|
||||||
|
if (_has_decide_type) {
|
||||||
|
if (_is_bce) {
|
||||||
|
std::string method = "POST";
|
||||||
|
sign(method, url, params, headers, ak, sk);
|
||||||
|
} else {
|
||||||
|
params["access_token"] = this->getAccessToken();
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getAccessToken() == "") {
|
||||||
|
_is_bce = true;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
const char * t = std::strstr(this->_scope.c_str(), "brain_all_scope");
|
||||||
|
|
||||||
|
if (t == NULL)
|
||||||
|
{
|
||||||
|
_is_bce = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_has_decide_type = true;
|
||||||
|
prepare_request(url, params, headers);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Json::Value requestjson(
|
||||||
|
std::string url,
|
||||||
|
Json::Value & data,
|
||||||
|
std::map<std::string, std::string> & params,
|
||||||
|
std::map<std::string, std::string> const & headers)
|
||||||
|
{
|
||||||
|
|
||||||
|
std::string response;
|
||||||
|
Json::Value obj;
|
||||||
|
auto headers_for_sign = headers;
|
||||||
|
auto temp_params = params;
|
||||||
|
this->prepare_request(url, temp_params, headers_for_sign);
|
||||||
|
int status_code = this->client.post(url, nullptr, data, nullptr, &response);
|
||||||
|
if (status_code != CURLcode::CURLE_OK) {
|
||||||
|
obj[aip::CURL_ERROR_CODE] = status_code;
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string error;
|
||||||
|
std::unique_ptr<Json::CharReader> reader(crbuilder.newCharReader());
|
||||||
|
reader->parse(response.data(), response.data() + response.size(), &obj, &error);
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
Json::Value request_com(
|
||||||
|
std::string const & url,
|
||||||
|
Json::Value & data)
|
||||||
|
{
|
||||||
|
std::string response;
|
||||||
|
Json::Value obj;
|
||||||
|
int status_code = this->client.post(url, nullptr, data, nullptr, &response);
|
||||||
|
|
||||||
|
if (status_code != CURLcode::CURLE_OK) {
|
||||||
|
obj[aip::CURL_ERROR_CODE] = status_code;
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
std::string error;
|
||||||
|
std::unique_ptr<Json::CharReader> reader(crbuilder.newCharReader());
|
||||||
|
reader->parse(response.data(), response.data() + response.size(), &obj, &error);
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,130 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2017 Baidu.com, Inc. All Rights Reserved
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||||
|
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations under the License.
|
||||||
|
*
|
||||||
|
* @author baidu aip
|
||||||
|
*/
|
||||||
|
#ifndef __AIP_BASE64_H__
|
||||||
|
#define __AIP_BASE64_H__
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace aip {
|
||||||
|
|
||||||
|
static const std::string base64_chars =
|
||||||
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||||
|
"abcdefghijklmnopqrstuvwxyz"
|
||||||
|
"0123456789+/";
|
||||||
|
|
||||||
|
|
||||||
|
static inline bool is_base64(const char c)
|
||||||
|
{
|
||||||
|
return (isalnum(c) || (c == '+') || (c == '/'));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string base64_encode(const char * bytes_to_encode, unsigned int in_len)
|
||||||
|
{
|
||||||
|
std::string ret;
|
||||||
|
int i = 0;
|
||||||
|
int j = 0;
|
||||||
|
unsigned char char_array_3[3];
|
||||||
|
unsigned char char_array_4[4];
|
||||||
|
|
||||||
|
while (in_len--)
|
||||||
|
{
|
||||||
|
char_array_3[i++] = *(bytes_to_encode++);
|
||||||
|
if(i == 3)
|
||||||
|
{
|
||||||
|
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
|
||||||
|
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
|
||||||
|
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
|
||||||
|
char_array_4[3] = char_array_3[2] & 0x3f;
|
||||||
|
|
||||||
|
for(i = 0; (i <4) ; i++)
|
||||||
|
{
|
||||||
|
ret += base64_chars[char_array_4[i]];
|
||||||
|
}
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(i)
|
||||||
|
{
|
||||||
|
for(j = i; j < 3; j++)
|
||||||
|
{
|
||||||
|
char_array_3[j] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
|
||||||
|
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
|
||||||
|
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
|
||||||
|
char_array_4[3] = char_array_3[2] & 0x3f;
|
||||||
|
|
||||||
|
for(j = 0; (j < i + 1); j++)
|
||||||
|
{
|
||||||
|
ret += base64_chars[char_array_4[j]];
|
||||||
|
}
|
||||||
|
|
||||||
|
while((i++ < 3))
|
||||||
|
{
|
||||||
|
ret += '=';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string base64_decode(std::string const & encoded_string)
|
||||||
|
{
|
||||||
|
int in_len = (int) encoded_string.size();
|
||||||
|
int i = 0;
|
||||||
|
int j = 0;
|
||||||
|
int in_ = 0;
|
||||||
|
unsigned char char_array_4[4], char_array_3[3];
|
||||||
|
std::string ret;
|
||||||
|
|
||||||
|
while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
|
||||||
|
char_array_4[i++] = encoded_string[in_]; in_++;
|
||||||
|
if (i ==4) {
|
||||||
|
for (i = 0; i <4; i++)
|
||||||
|
char_array_4[i] = base64_chars.find(char_array_4[i]);
|
||||||
|
|
||||||
|
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
|
||||||
|
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
|
||||||
|
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
|
||||||
|
|
||||||
|
for (i = 0; (i < 3); i++)
|
||||||
|
ret += char_array_3[i];
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i) {
|
||||||
|
for (j = i; j <4; j++)
|
||||||
|
char_array_4[j] = 0;
|
||||||
|
|
||||||
|
for (j = 0; j <4; j++)
|
||||||
|
char_array_4[j] = base64_chars.find(char_array_4[j]);
|
||||||
|
|
||||||
|
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
|
||||||
|
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
|
||||||
|
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
|
||||||
|
|
||||||
|
for (j = 0; (j < i - 1); j++) ret += char_array_3[j];
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,234 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2017 Baidu.com, Inc. All Rights Reserved
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||||
|
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations under the License.
|
||||||
|
*
|
||||||
|
* @author baidu aip
|
||||||
|
*/
|
||||||
|
#ifndef __AIP_HTTP_H__
|
||||||
|
#define __AIP_HTTP_H__
|
||||||
|
|
||||||
|
#include "curl/curl.h"
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
|
#include <map>
|
||||||
|
#include <json/json.h>
|
||||||
|
|
||||||
|
namespace aip {
|
||||||
|
|
||||||
|
inline size_t onWriteData(void * buffer, size_t size, size_t nmemb, void * userp)
|
||||||
|
{
|
||||||
|
std::string * str = dynamic_cast<std::string *>((std::string *)userp);
|
||||||
|
str->append((char *)buffer, size * nmemb);
|
||||||
|
return nmemb;
|
||||||
|
}
|
||||||
|
|
||||||
|
class HttpClient
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
bool debug = false;
|
||||||
|
int connect_timeout = 10000;
|
||||||
|
int socket_timeout = 10000;
|
||||||
|
|
||||||
|
void makeUrlencodedForm(std::map<std::string, std::string> const & params, std::string * content) const
|
||||||
|
{
|
||||||
|
content->clear();
|
||||||
|
std::map<std::string, std::string>::const_iterator it;
|
||||||
|
for(it=params.begin(); it!=params.end(); it++)
|
||||||
|
{
|
||||||
|
char * key = curl_escape(it->first.c_str(), (int) it->first.size());
|
||||||
|
char * value = curl_escape(it->second.c_str(),(int) it->second.size());
|
||||||
|
*content += key;
|
||||||
|
*content += '=';
|
||||||
|
*content += value;
|
||||||
|
*content += '&';
|
||||||
|
curl_free(key);
|
||||||
|
curl_free(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void appendUrlParams(std::map<std::string, std::string> const & params, std::string* url) const
|
||||||
|
{
|
||||||
|
if(params.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
std::string content;
|
||||||
|
this->makeUrlencodedForm(params, &content);
|
||||||
|
bool url_has_param = false;
|
||||||
|
for (const auto& ch : *url) {
|
||||||
|
if (ch == '?') {
|
||||||
|
url_has_param = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (url_has_param) {
|
||||||
|
url->append("&");
|
||||||
|
} else {
|
||||||
|
url->append("?");
|
||||||
|
}
|
||||||
|
url->append(content);
|
||||||
|
}
|
||||||
|
|
||||||
|
void appendHeaders(std::map<std::string, std::string> const & headers, curl_slist ** slist) const
|
||||||
|
{
|
||||||
|
std::ostringstream ostr;
|
||||||
|
std::map<std::string, std::string>::const_iterator it;
|
||||||
|
for(it=headers.begin(); it!=headers.end(); it++)
|
||||||
|
{
|
||||||
|
ostr << it->first << ":" << it->second;
|
||||||
|
*slist = curl_slist_append(*slist, ostr.str().c_str());
|
||||||
|
ostr.str("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
HttpClient() = default;
|
||||||
|
|
||||||
|
HttpClient(const HttpClient &) = delete;
|
||||||
|
HttpClient & operator=(const HttpClient &) = delete;
|
||||||
|
|
||||||
|
void setConnectTimeout(int connect_timeout)
|
||||||
|
{
|
||||||
|
this->connect_timeout = connect_timeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setSocketTimeout(int socket_timeout)
|
||||||
|
{
|
||||||
|
this->socket_timeout = socket_timeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setDebug(bool debug)
|
||||||
|
{
|
||||||
|
this->debug = debug;
|
||||||
|
}
|
||||||
|
|
||||||
|
int get(
|
||||||
|
std::string url,
|
||||||
|
std::map<std::string, std::string> const * params,
|
||||||
|
std::map<std::string, std::string> const * headers,
|
||||||
|
std::string * response) const
|
||||||
|
{
|
||||||
|
CURL * curl = curl_easy_init();
|
||||||
|
struct curl_slist * slist = NULL;
|
||||||
|
if (headers) {
|
||||||
|
this->appendHeaders(*headers, &slist);
|
||||||
|
}
|
||||||
|
if (params) {
|
||||||
|
this->appendUrlParams(*params, &url);
|
||||||
|
}
|
||||||
|
|
||||||
|
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
|
||||||
|
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, onWriteData);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *) response);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, true);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT_MS, this->connect_timeout);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, this->socket_timeout);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_VERBOSE, this->debug);
|
||||||
|
|
||||||
|
int status_code = curl_easy_perform(curl);
|
||||||
|
|
||||||
|
curl_easy_cleanup(curl);
|
||||||
|
curl_slist_free_all(slist);
|
||||||
|
|
||||||
|
return status_code;
|
||||||
|
}
|
||||||
|
|
||||||
|
int post(
|
||||||
|
std::string url,
|
||||||
|
std::map<std::string, std::string> const * params,
|
||||||
|
const std::string & body,
|
||||||
|
std::map<std::string, std::string> const * headers,
|
||||||
|
std::string * response) const
|
||||||
|
{
|
||||||
|
struct curl_slist * slist = NULL;
|
||||||
|
CURL * curl = curl_easy_init();
|
||||||
|
if (headers) {
|
||||||
|
this->appendHeaders(*headers, &slist);
|
||||||
|
}
|
||||||
|
if (params) {
|
||||||
|
this->appendUrlParams(*params, &url);
|
||||||
|
}
|
||||||
|
|
||||||
|
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
|
||||||
|
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_POST, true);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body.c_str());
|
||||||
|
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, body.size());
|
||||||
|
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, onWriteData);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *) response);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, true);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT_MS, this->connect_timeout);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, this->socket_timeout);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_VERBOSE, this->debug);
|
||||||
|
|
||||||
|
int status_code = curl_easy_perform(curl);
|
||||||
|
|
||||||
|
curl_easy_cleanup(curl);
|
||||||
|
curl_slist_free_all(slist);
|
||||||
|
|
||||||
|
return status_code;
|
||||||
|
}
|
||||||
|
|
||||||
|
int post(
|
||||||
|
std::string url,
|
||||||
|
std::map<std::string, std::string> const * params,
|
||||||
|
std::map<std::string, std::string> const & data,
|
||||||
|
std::map<std::string, std::string> const * headers,
|
||||||
|
std::string * response) const
|
||||||
|
{
|
||||||
|
|
||||||
|
std::string body;
|
||||||
|
this->makeUrlencodedForm(data, &body);
|
||||||
|
return this->post(std::move(url), params, body, headers, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
int post(
|
||||||
|
std::string url,
|
||||||
|
std::map<std::string, std::string> const * params,
|
||||||
|
Json::Value const & data,
|
||||||
|
std::map<std::string, std::string> const * headers,
|
||||||
|
std::string * response) const
|
||||||
|
{
|
||||||
|
std::string body;
|
||||||
|
Json::StreamWriterBuilder swb;
|
||||||
|
std::unique_ptr<Json::StreamWriter> writer(swb.newStreamWriter());
|
||||||
|
std::ostringstream os;
|
||||||
|
writer->write(data, &os);
|
||||||
|
body = os.str();
|
||||||
|
std::map<std::string, std::string> temp_headers;
|
||||||
|
if (headers) {
|
||||||
|
std::map<std::string, std::string> temp_headers(*headers);
|
||||||
|
}
|
||||||
|
|
||||||
|
temp_headers["Content-Type"] = "application/json";
|
||||||
|
return this->post(url.c_str(), params, body, &temp_headers, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int post(
|
||||||
|
std::string url,
|
||||||
|
std::map<std::string, std::string> const * params,
|
||||||
|
std::map<std::string, std::string> const * headers,
|
||||||
|
std::string * response) const
|
||||||
|
{
|
||||||
|
const static std::string EMPTY_STRING;
|
||||||
|
return this->post(std::move(url), params, EMPTY_STRING, headers, response);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,283 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2017 Baidu.com, Inc. All Rights Reserved
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||||
|
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations under the License.
|
||||||
|
*
|
||||||
|
* @author baidu aip
|
||||||
|
*/
|
||||||
|
#ifndef __AIP_UTILS_H__
|
||||||
|
#define __AIP_UTILS_H__
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <fstream>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <openssl/evp.h>
|
||||||
|
#include <openssl/hmac.h>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <openssl/md5.h>
|
||||||
|
|
||||||
|
const int __BCE_VERSION__ = 1;
|
||||||
|
const int __BCE_EXPIRE__ = 1800;
|
||||||
|
|
||||||
|
namespace aip {
|
||||||
|
|
||||||
|
template<class CharT, class Traits, class Allocator>
|
||||||
|
std::basic_istream<CharT, Traits>& getall(std::basic_istream<CharT, Traits>& input,
|
||||||
|
std::basic_string<CharT, Traits, Allocator>& str) {
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << input.rdbuf();
|
||||||
|
str.assign(oss.str());
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int get_file_content(const char *filename, std::string* out) {
|
||||||
|
std::ifstream in(filename, std::ios::in | std::ios::binary);
|
||||||
|
if (in) {
|
||||||
|
getall(in, *out);
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::string to_upper(std::string src)
|
||||||
|
{
|
||||||
|
std::transform(src.begin(), src.end(), src.begin(), toupper);
|
||||||
|
return src;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline std::string to_lower(std::string src)
|
||||||
|
{
|
||||||
|
std::transform(src.begin(), src.end(), src.begin(), tolower);
|
||||||
|
return src;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::string to_hex(unsigned char c, bool lower = false)
|
||||||
|
{
|
||||||
|
const std::string hex = "0123456789ABCDEF";
|
||||||
|
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << hex[c >> 4] << hex[c & 0xf];
|
||||||
|
|
||||||
|
return lower ? to_lower(ss.str()) : ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline time_t now()
|
||||||
|
{
|
||||||
|
return time(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string utc_time(time_t timestamp)
|
||||||
|
{
|
||||||
|
struct tm result_tm;
|
||||||
|
char buffer[32];
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
gmtime_s(&result_tm, ×tamp);
|
||||||
|
#else
|
||||||
|
gmtime_r(×tamp, &result_tm);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
size_t size = strftime(buffer, 32, "%Y-%m-%dT%H:%M:%SZ", &result_tm);
|
||||||
|
|
||||||
|
return std::string(buffer, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void url_parse(
|
||||||
|
const std::string & url,
|
||||||
|
std::map<std::string, std::string> & params)
|
||||||
|
{
|
||||||
|
int pos = (int)url.find("?");
|
||||||
|
if (pos != -1)
|
||||||
|
{
|
||||||
|
int key_start = pos + 1,
|
||||||
|
key_len = 0,
|
||||||
|
val_start = 0;
|
||||||
|
for (int i = key_start; i <= (int)url.size(); ++i)
|
||||||
|
{
|
||||||
|
switch (url[i])
|
||||||
|
{
|
||||||
|
case '=':
|
||||||
|
key_len = i - key_start;
|
||||||
|
val_start = i + 1;
|
||||||
|
break;
|
||||||
|
case '\0':
|
||||||
|
case '&':
|
||||||
|
if (key_len != 0)
|
||||||
|
{
|
||||||
|
params[url.substr(key_start, key_len)] = url.substr(val_start, i - val_start);
|
||||||
|
key_start = i + 1;
|
||||||
|
key_len = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string url_encode(const std::string & input, bool encode_slash=true)
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
const char *str = input.c_str();
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < input.size(); i++)
|
||||||
|
{
|
||||||
|
unsigned char c = str[i];
|
||||||
|
if (isalnum(c) || c == '_' || c == '-' || c == '~' || c == '.' || (!encode_slash && c == '/'))
|
||||||
|
{
|
||||||
|
ss << c;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ss << "%" << to_hex(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string canonicalize_params(std::map<std::string, std::string> & params)
|
||||||
|
{
|
||||||
|
std::vector<std::string> v;
|
||||||
|
v.reserve(params.size());
|
||||||
|
|
||||||
|
for (auto & it : params) {
|
||||||
|
v.push_back(url_encode(it.first) + "=" + url_encode(it.second));
|
||||||
|
}
|
||||||
|
std::sort(v.begin(), v.end());
|
||||||
|
|
||||||
|
std::string result;
|
||||||
|
for (auto & it : v)
|
||||||
|
{
|
||||||
|
result.append((result.empty() ? "" : "&") + it);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string canonicalize_headers(std::map<std::string, std::string> & headers)
|
||||||
|
{
|
||||||
|
std::vector<std::string> v;
|
||||||
|
v.reserve(headers.size());
|
||||||
|
|
||||||
|
for (auto & it : headers) {
|
||||||
|
v.push_back(url_encode(to_lower(it.first)) + ":" + url_encode(it.second));
|
||||||
|
}
|
||||||
|
std::sort(v.begin(), v.end());
|
||||||
|
|
||||||
|
std::string result;
|
||||||
|
for (auto & it : v)
|
||||||
|
{
|
||||||
|
result.append((result.empty() ? "" : "\n") + it);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string get_headers_keys(std::map<std::string, std::string> & headers)
|
||||||
|
{
|
||||||
|
std::vector<std::string> v;
|
||||||
|
v.reserve(headers.size());
|
||||||
|
|
||||||
|
for (auto & it : headers) {
|
||||||
|
v.push_back(to_lower(it.first));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string result;
|
||||||
|
for (auto & it : v)
|
||||||
|
{
|
||||||
|
result.append((result.empty() ? "" : ";") + it);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string get_host(const std::string & url)
|
||||||
|
{
|
||||||
|
int pos = (int)url.find("://") + 3;
|
||||||
|
return url.substr(
|
||||||
|
pos,
|
||||||
|
url.find('/', pos) - pos
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::string get_path(const std::string & url)
|
||||||
|
{
|
||||||
|
int path_start = (int)url.find('/', url.find("://") + 3);
|
||||||
|
int path_end = (int)url.find('?');
|
||||||
|
path_end = path_end == -1 ? (int)url.size() : path_end;
|
||||||
|
|
||||||
|
return url.substr(path_start, path_end - path_start);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string hmac_sha256(
|
||||||
|
const std::string & src,
|
||||||
|
const std::string & sk)
|
||||||
|
{
|
||||||
|
const EVP_MD *evp_md = EVP_sha256();
|
||||||
|
unsigned char md[EVP_MAX_MD_SIZE];
|
||||||
|
unsigned int md_len = 0;
|
||||||
|
|
||||||
|
if (HMAC(evp_md,
|
||||||
|
reinterpret_cast<const unsigned char *>(sk.data()), (int)sk.size(),
|
||||||
|
reinterpret_cast<const unsigned char *>(src.data()), src.size(),
|
||||||
|
md, &md_len) == NULL)
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::stringstream ss;
|
||||||
|
for (int i = 0; i < (int)md_len; ++i)
|
||||||
|
{
|
||||||
|
ss << to_hex(md[i], true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
void sign(
|
||||||
|
std::string method,
|
||||||
|
std::string & url,
|
||||||
|
std::map<std::string, std::string> & params,
|
||||||
|
std::map<std::string, std::string> & headers,
|
||||||
|
std::string & ak,
|
||||||
|
std::string & sk)
|
||||||
|
{
|
||||||
|
url_parse(url, params);
|
||||||
|
headers["Host"] = get_host(url);
|
||||||
|
std::string timestamp = utc_time(now());
|
||||||
|
headers["x-bce-date"] = timestamp;
|
||||||
|
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << "bce-auth-v" << __BCE_VERSION__ << "/" << ak << "/"
|
||||||
|
<< timestamp << "/" << __BCE_EXPIRE__;
|
||||||
|
|
||||||
|
std::string val = ss.str();
|
||||||
|
std::string sign_key = hmac_sha256(val, sk);
|
||||||
|
|
||||||
|
ss.str("");
|
||||||
|
ss << to_upper(method) << '\n' << url_encode(get_path(url), false)
|
||||||
|
<< '\n' << canonicalize_params(params)
|
||||||
|
<< '\n' << canonicalize_headers(headers);
|
||||||
|
|
||||||
|
std::string signature = hmac_sha256(ss.str(), sign_key);
|
||||||
|
|
||||||
|
ss.str("");
|
||||||
|
ss << "bce-auth-v" << __BCE_VERSION__ << "/" << ak << "/"
|
||||||
|
<< timestamp << "/" << __BCE_EXPIRE__ << "/"
|
||||||
|
<< get_headers_keys(headers) << "/" << signature;
|
||||||
|
|
||||||
|
headers["authorization"] = ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include "ocr.h" // 用于调用接口
|
||||||
|
#include <string> // 用于 string 的操作
|
||||||
|
#include <codecvt> // 用于转码
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
int main(int argc, char const *argv[]) // argc: 参数个数, argv: 参数列表
|
||||||
|
{
|
||||||
|
if (argc < 2)
|
||||||
|
{
|
||||||
|
cout << "Usage: " << argv[0] << "车牌照片路径" << endl;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
string app_id = "35458273"; // 你的 App ID
|
||||||
|
string api_key = "i45yQx4IaGoxxULLDVPl4iNj"; // 你的 Api Key
|
||||||
|
string secret_key = "jnt90aTbXCOp9L7gRB1xq1C3iT0bLuie"; // 你的 Secret Key
|
||||||
|
|
||||||
|
aip::Ocr client(app_id, api_key, secret_key); // 新建一个对象, 用于调用接口, 调用通用文字识别, 图片参数为本地图片
|
||||||
|
cout << "ok" << endl;
|
||||||
|
|
||||||
|
// 定义 json 格式的数据类型 Value, result 是 json 类型的 Value 类实例, 用于存储返回的结果
|
||||||
|
Json::Value result;
|
||||||
|
string image;
|
||||||
|
|
||||||
|
// 加载本地的车牌图片内容到 image 对象中, 用于调用车牌识别
|
||||||
|
// aip::get_file_content("R-C.jpg", &image);
|
||||||
|
aip::get_file_content(argv[1], &image);
|
||||||
|
|
||||||
|
// 客户端发送图片内容到百度服务器, 并返回结果到 result 对象中
|
||||||
|
result = client.license_plate(image, aip::null);
|
||||||
|
// cout << result << endl;
|
||||||
|
cout << "车牌颜色: " << result["words_result"]["color"] << endl;
|
||||||
|
cout << "车牌号码: " << result["words_result"]["number"].asString() << endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
cc = g++
|
||||||
|
cflags = -Wall -lssl -lcrypto -lcurl -ljsoncpp
|
||||||
|
cflags += -I/home/flykhan/.tools/openssl_build/include/
|
||||||
|
cflags += -I/home/flykhan/.tools/curl/include/
|
||||||
|
cflags += -I/home/flykhan/.tools/jsoncpp-Sandbox/jsoncpp-build/include/
|
||||||
|
cflags += -L/home/flykhan/.tools/openssl_build/lib/
|
||||||
|
cflags += -L/home/flykhan/.tools/curl/lib/
|
||||||
|
cflags += -L/home/flykhan/.tools/jsoncpp-Sandbox/jsoncpp-build/lib/
|
||||||
|
|
||||||
|
idCard:
|
||||||
|
$(cc) idCard.cpp -o idCard $(cflags) -std=c++14
|
||||||
|
|
||||||
|
bankCard:
|
||||||
|
$(cc) bankCard.cpp -o bankCard $(cflags) -std=c++14
|
||||||
|
|
||||||
|
driverLicense:
|
||||||
|
$(cc) driverLicense.cpp -o driverLicense $(cflags) -std=c++14
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm *.o idCard bankCard driverLicense -rf
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include "ocr.h" // 用于调用接口
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
string cardType(int);
|
||||||
|
|
||||||
|
int main(int argc, char const *argv[])
|
||||||
|
{
|
||||||
|
if (argc < 2)
|
||||||
|
{
|
||||||
|
cout << "用法: " << argv[0] << " 银行卡照片" << endl;
|
||||||
|
return -1; // 返回 -1 表示程序异常退出
|
||||||
|
}
|
||||||
|
|
||||||
|
string app_id = "35475147"; // 你的 App ID
|
||||||
|
string api_key = "CSneGCoRs8zMD1F1PPnXyzPP"; // 你的 Api Key
|
||||||
|
string secret_key = "wlKjVS2lE9xPFVV7G5EI3gYm7Zk3tnu1"; // 你的 Secret Key
|
||||||
|
|
||||||
|
aip::Ocr client(app_id, api_key, secret_key); // 新建一个对象, 用于调用接口, 调用通用文字识别, 图片参数为本地图片
|
||||||
|
// cout << "ok" << endl;
|
||||||
|
|
||||||
|
// 定义 json 格式的数据类型 Value, result 是 json 类型的 Value 类实例, 用于存储返回的结果
|
||||||
|
Json::Value result;
|
||||||
|
string image; // 用于存储图片内容
|
||||||
|
|
||||||
|
// 加载本地的银行卡图片内容到 image 对象中, 用于调用银行卡识别
|
||||||
|
aip::get_file_content(argv[1], &image);
|
||||||
|
|
||||||
|
// 客户端发送图片内容到百度服务器, 并返回结果到 result 对象中
|
||||||
|
result = client.bankcard(image, aip::null);
|
||||||
|
|
||||||
|
int cardTypeNum = result["result"]["bank_card_type"].asInt(); // 卡类型判定 0:不能识别; 1: 借记卡; 2: 信用卡
|
||||||
|
|
||||||
|
cout << "识别到的银行卡信息如下: " << endl;
|
||||||
|
cout << "发卡行: " << result["result"]["bank_name"].asString() << endl;
|
||||||
|
cout << "卡号: " << result["result"]["bank_card_number"].asString() << endl;
|
||||||
|
cout << "卡类型: " << cardType(cardTypeNum) << endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 卡类型判定 0:不能识别; 1: 借记卡; 2: 信用卡
|
||||||
|
string cardType(int type)
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
return "不能识别";
|
||||||
|
case 1:
|
||||||
|
return "借记卡";
|
||||||
|
case 2:
|
||||||
|
return "信用卡";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,264 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2017 Baidu.com, Inc. All Rights Reserved
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||||
|
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations under the License.
|
||||||
|
*
|
||||||
|
* @author baidu aip
|
||||||
|
*/
|
||||||
|
#ifndef __AIP_BASE_H__
|
||||||
|
#define __AIP_BASE_H__
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <cstring>
|
||||||
|
#include "http.h"
|
||||||
|
#include "json/json.h"
|
||||||
|
#include "base64.h"
|
||||||
|
#include "curl/curl.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
namespace aip {
|
||||||
|
|
||||||
|
static const char* AIP_SDK_VERSION = "0.3.3";
|
||||||
|
static const char* CURL_ERROR_CODE = "curl_error_code";
|
||||||
|
static const std::string ACCESS_TOKEN_URL = "https://aip.baidubce.com/oauth/2.0/token";
|
||||||
|
static const std::map<std::string, std::string> null;
|
||||||
|
|
||||||
|
class AipBase
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
std::string _app_id;
|
||||||
|
int _expired_time;
|
||||||
|
bool _is_bce;
|
||||||
|
bool _has_decide_type;
|
||||||
|
std::string _scope;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::string getAccessToken()
|
||||||
|
{
|
||||||
|
time_t now = time(NULL);
|
||||||
|
if (!access_token.empty())
|
||||||
|
{
|
||||||
|
return this->access_token;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (now < this->_expired_time - 60 * 60 * 24)
|
||||||
|
{
|
||||||
|
return this->access_token;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string response;
|
||||||
|
std::map<std::string, std::string> params;
|
||||||
|
|
||||||
|
params["grant_type"] = "client_credentials";
|
||||||
|
params["client_id"] = this->ak;
|
||||||
|
params["client_secret"] = this->sk;
|
||||||
|
int status_code = this->client.get(
|
||||||
|
ACCESS_TOKEN_URL,
|
||||||
|
¶ms,
|
||||||
|
nullptr,
|
||||||
|
&response
|
||||||
|
);
|
||||||
|
Json::Value obj;
|
||||||
|
if (status_code != CURLcode::CURLE_OK) {
|
||||||
|
obj[CURL_ERROR_CODE] = status_code;
|
||||||
|
return obj.toStyledString();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string error;
|
||||||
|
std::unique_ptr<Json::CharReader> reader(crbuilder.newCharReader());
|
||||||
|
reader->parse(response.data(), response.data() + response.size(), &obj, &error);
|
||||||
|
this->access_token = obj["access_token"].asString();
|
||||||
|
this->_expired_time = obj["expires_in"].asInt() + (int) now;
|
||||||
|
this->_scope = obj["scope"].asString();
|
||||||
|
return this->access_token;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
std::string ak;
|
||||||
|
std::string sk;
|
||||||
|
HttpClient client;
|
||||||
|
Json::CharReaderBuilder crbuilder;
|
||||||
|
std::string access_token;
|
||||||
|
AipBase(const std::string & app_id, const std::string & ak, const std::string & sk):
|
||||||
|
_app_id(app_id),
|
||||||
|
_is_bce(false),
|
||||||
|
_has_decide_type(false),
|
||||||
|
ak(ak),
|
||||||
|
sk(sk)
|
||||||
|
{
|
||||||
|
if (_app_id == "")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setConnectionTimeoutInMillis(int connect_timeout)
|
||||||
|
{
|
||||||
|
this->client.setConnectTimeout(connect_timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setSocketTimeoutInMillis(int socket_timeout)
|
||||||
|
{
|
||||||
|
this->client.setSocketTimeout(socket_timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setDebug(bool debug)
|
||||||
|
{
|
||||||
|
this->client.setDebug(debug);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string getAk() {
|
||||||
|
return ak;
|
||||||
|
}
|
||||||
|
|
||||||
|
Json::Value request(
|
||||||
|
std::string url,
|
||||||
|
std::map<std::string, std::string> const & params,
|
||||||
|
std::string const & data,
|
||||||
|
std::map<std::string, std::string> const & headers)
|
||||||
|
{
|
||||||
|
std::string response;
|
||||||
|
Json::Value obj;
|
||||||
|
std::string body;
|
||||||
|
auto headers_for_sign = headers;
|
||||||
|
|
||||||
|
auto temp_params = params;
|
||||||
|
|
||||||
|
temp_params["charset"] = "UTF-8";
|
||||||
|
|
||||||
|
this->prepare_request(url, temp_params, headers_for_sign);
|
||||||
|
|
||||||
|
int status_code = this->client.post(url, &temp_params, data, &headers_for_sign, &response);
|
||||||
|
|
||||||
|
if (status_code != CURLcode::CURLE_OK) {
|
||||||
|
obj[CURL_ERROR_CODE] = status_code;
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string error;
|
||||||
|
std::unique_ptr<Json::CharReader> reader(crbuilder.newCharReader());
|
||||||
|
reader->parse(response.data(), response.data() + response.size(), &obj, &error);
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
Json::Value request(
|
||||||
|
std::string url,
|
||||||
|
std::map<std::string, std::string> const & params,
|
||||||
|
std::map<std::string, std::string> const & data,
|
||||||
|
std::map<std::string, std::string> const & headers)
|
||||||
|
{
|
||||||
|
std::string response;
|
||||||
|
Json::Value obj;
|
||||||
|
|
||||||
|
auto headers_for_sign = headers;
|
||||||
|
auto temp_params = params;
|
||||||
|
|
||||||
|
this->prepare_request(url, temp_params, headers_for_sign);
|
||||||
|
|
||||||
|
int status_code = this->client.post(url, &temp_params, data, &headers_for_sign, &response);
|
||||||
|
|
||||||
|
if (status_code != CURLcode::CURLE_OK) {
|
||||||
|
obj[CURL_ERROR_CODE] = status_code;
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string error;
|
||||||
|
std::unique_ptr<Json::CharReader> reader(crbuilder.newCharReader());
|
||||||
|
reader->parse(response.data(), response.data() + response.size(), &obj, &error);
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
void prepare_request(std::string url,
|
||||||
|
std::map<std::string, std::string> & params,
|
||||||
|
std::map<std::string, std::string> & headers)
|
||||||
|
{
|
||||||
|
|
||||||
|
params["aipSdk"] = "C";
|
||||||
|
params["aipSdkVersion"] = AIP_SDK_VERSION;
|
||||||
|
|
||||||
|
if (_has_decide_type) {
|
||||||
|
if (_is_bce) {
|
||||||
|
std::string method = "POST";
|
||||||
|
sign(method, url, params, headers, ak, sk);
|
||||||
|
} else {
|
||||||
|
params["access_token"] = this->getAccessToken();
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getAccessToken() == "") {
|
||||||
|
_is_bce = true;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
const char * t = std::strstr(this->_scope.c_str(), "brain_all_scope");
|
||||||
|
|
||||||
|
if (t == NULL)
|
||||||
|
{
|
||||||
|
_is_bce = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_has_decide_type = true;
|
||||||
|
prepare_request(url, params, headers);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Json::Value requestjson(
|
||||||
|
std::string url,
|
||||||
|
Json::Value & data,
|
||||||
|
std::map<std::string, std::string> & params,
|
||||||
|
std::map<std::string, std::string> const & headers)
|
||||||
|
{
|
||||||
|
|
||||||
|
std::string response;
|
||||||
|
Json::Value obj;
|
||||||
|
auto headers_for_sign = headers;
|
||||||
|
auto temp_params = params;
|
||||||
|
this->prepare_request(url, temp_params, headers_for_sign);
|
||||||
|
int status_code = this->client.post(url, nullptr, data, nullptr, &response);
|
||||||
|
if (status_code != CURLcode::CURLE_OK) {
|
||||||
|
obj[aip::CURL_ERROR_CODE] = status_code;
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string error;
|
||||||
|
std::unique_ptr<Json::CharReader> reader(crbuilder.newCharReader());
|
||||||
|
reader->parse(response.data(), response.data() + response.size(), &obj, &error);
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
Json::Value request_com(
|
||||||
|
std::string const & url,
|
||||||
|
Json::Value & data)
|
||||||
|
{
|
||||||
|
std::string response;
|
||||||
|
Json::Value obj;
|
||||||
|
int status_code = this->client.post(url, nullptr, data, nullptr, &response);
|
||||||
|
|
||||||
|
if (status_code != CURLcode::CURLE_OK) {
|
||||||
|
obj[aip::CURL_ERROR_CODE] = status_code;
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
std::string error;
|
||||||
|
std::unique_ptr<Json::CharReader> reader(crbuilder.newCharReader());
|
||||||
|
reader->parse(response.data(), response.data() + response.size(), &obj, &error);
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,130 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2017 Baidu.com, Inc. All Rights Reserved
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||||
|
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations under the License.
|
||||||
|
*
|
||||||
|
* @author baidu aip
|
||||||
|
*/
|
||||||
|
#ifndef __AIP_BASE64_H__
|
||||||
|
#define __AIP_BASE64_H__
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace aip {
|
||||||
|
|
||||||
|
static const std::string base64_chars =
|
||||||
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||||
|
"abcdefghijklmnopqrstuvwxyz"
|
||||||
|
"0123456789+/";
|
||||||
|
|
||||||
|
|
||||||
|
static inline bool is_base64(const char c)
|
||||||
|
{
|
||||||
|
return (isalnum(c) || (c == '+') || (c == '/'));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string base64_encode(const char * bytes_to_encode, unsigned int in_len)
|
||||||
|
{
|
||||||
|
std::string ret;
|
||||||
|
int i = 0;
|
||||||
|
int j = 0;
|
||||||
|
unsigned char char_array_3[3];
|
||||||
|
unsigned char char_array_4[4];
|
||||||
|
|
||||||
|
while (in_len--)
|
||||||
|
{
|
||||||
|
char_array_3[i++] = *(bytes_to_encode++);
|
||||||
|
if(i == 3)
|
||||||
|
{
|
||||||
|
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
|
||||||
|
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
|
||||||
|
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
|
||||||
|
char_array_4[3] = char_array_3[2] & 0x3f;
|
||||||
|
|
||||||
|
for(i = 0; (i <4) ; i++)
|
||||||
|
{
|
||||||
|
ret += base64_chars[char_array_4[i]];
|
||||||
|
}
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(i)
|
||||||
|
{
|
||||||
|
for(j = i; j < 3; j++)
|
||||||
|
{
|
||||||
|
char_array_3[j] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
|
||||||
|
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
|
||||||
|
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
|
||||||
|
char_array_4[3] = char_array_3[2] & 0x3f;
|
||||||
|
|
||||||
|
for(j = 0; (j < i + 1); j++)
|
||||||
|
{
|
||||||
|
ret += base64_chars[char_array_4[j]];
|
||||||
|
}
|
||||||
|
|
||||||
|
while((i++ < 3))
|
||||||
|
{
|
||||||
|
ret += '=';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string base64_decode(std::string const & encoded_string)
|
||||||
|
{
|
||||||
|
int in_len = (int) encoded_string.size();
|
||||||
|
int i = 0;
|
||||||
|
int j = 0;
|
||||||
|
int in_ = 0;
|
||||||
|
unsigned char char_array_4[4], char_array_3[3];
|
||||||
|
std::string ret;
|
||||||
|
|
||||||
|
while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
|
||||||
|
char_array_4[i++] = encoded_string[in_]; in_++;
|
||||||
|
if (i ==4) {
|
||||||
|
for (i = 0; i <4; i++)
|
||||||
|
char_array_4[i] = base64_chars.find(char_array_4[i]);
|
||||||
|
|
||||||
|
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
|
||||||
|
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
|
||||||
|
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
|
||||||
|
|
||||||
|
for (i = 0; (i < 3); i++)
|
||||||
|
ret += char_array_3[i];
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i) {
|
||||||
|
for (j = i; j <4; j++)
|
||||||
|
char_array_4[j] = 0;
|
||||||
|
|
||||||
|
for (j = 0; j <4; j++)
|
||||||
|
char_array_4[j] = base64_chars.find(char_array_4[j]);
|
||||||
|
|
||||||
|
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
|
||||||
|
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
|
||||||
|
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
|
||||||
|
|
||||||
|
for (j = 0; (j < i - 1); j++) ret += char_array_3[j];
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,234 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2017 Baidu.com, Inc. All Rights Reserved
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||||
|
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations under the License.
|
||||||
|
*
|
||||||
|
* @author baidu aip
|
||||||
|
*/
|
||||||
|
#ifndef __AIP_HTTP_H__
|
||||||
|
#define __AIP_HTTP_H__
|
||||||
|
|
||||||
|
#include "curl/curl.h"
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
|
#include <map>
|
||||||
|
#include <json/json.h>
|
||||||
|
|
||||||
|
namespace aip {
|
||||||
|
|
||||||
|
inline size_t onWriteData(void * buffer, size_t size, size_t nmemb, void * userp)
|
||||||
|
{
|
||||||
|
std::string * str = dynamic_cast<std::string *>((std::string *)userp);
|
||||||
|
str->append((char *)buffer, size * nmemb);
|
||||||
|
return nmemb;
|
||||||
|
}
|
||||||
|
|
||||||
|
class HttpClient
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
bool debug = false;
|
||||||
|
int connect_timeout = 10000;
|
||||||
|
int socket_timeout = 10000;
|
||||||
|
|
||||||
|
void makeUrlencodedForm(std::map<std::string, std::string> const & params, std::string * content) const
|
||||||
|
{
|
||||||
|
content->clear();
|
||||||
|
std::map<std::string, std::string>::const_iterator it;
|
||||||
|
for(it=params.begin(); it!=params.end(); it++)
|
||||||
|
{
|
||||||
|
char * key = curl_escape(it->first.c_str(), (int) it->first.size());
|
||||||
|
char * value = curl_escape(it->second.c_str(),(int) it->second.size());
|
||||||
|
*content += key;
|
||||||
|
*content += '=';
|
||||||
|
*content += value;
|
||||||
|
*content += '&';
|
||||||
|
curl_free(key);
|
||||||
|
curl_free(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void appendUrlParams(std::map<std::string, std::string> const & params, std::string* url) const
|
||||||
|
{
|
||||||
|
if(params.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
std::string content;
|
||||||
|
this->makeUrlencodedForm(params, &content);
|
||||||
|
bool url_has_param = false;
|
||||||
|
for (const auto& ch : *url) {
|
||||||
|
if (ch == '?') {
|
||||||
|
url_has_param = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (url_has_param) {
|
||||||
|
url->append("&");
|
||||||
|
} else {
|
||||||
|
url->append("?");
|
||||||
|
}
|
||||||
|
url->append(content);
|
||||||
|
}
|
||||||
|
|
||||||
|
void appendHeaders(std::map<std::string, std::string> const & headers, curl_slist ** slist) const
|
||||||
|
{
|
||||||
|
std::ostringstream ostr;
|
||||||
|
std::map<std::string, std::string>::const_iterator it;
|
||||||
|
for(it=headers.begin(); it!=headers.end(); it++)
|
||||||
|
{
|
||||||
|
ostr << it->first << ":" << it->second;
|
||||||
|
*slist = curl_slist_append(*slist, ostr.str().c_str());
|
||||||
|
ostr.str("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
HttpClient() = default;
|
||||||
|
|
||||||
|
HttpClient(const HttpClient &) = delete;
|
||||||
|
HttpClient & operator=(const HttpClient &) = delete;
|
||||||
|
|
||||||
|
void setConnectTimeout(int connect_timeout)
|
||||||
|
{
|
||||||
|
this->connect_timeout = connect_timeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setSocketTimeout(int socket_timeout)
|
||||||
|
{
|
||||||
|
this->socket_timeout = socket_timeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setDebug(bool debug)
|
||||||
|
{
|
||||||
|
this->debug = debug;
|
||||||
|
}
|
||||||
|
|
||||||
|
int get(
|
||||||
|
std::string url,
|
||||||
|
std::map<std::string, std::string> const * params,
|
||||||
|
std::map<std::string, std::string> const * headers,
|
||||||
|
std::string * response) const
|
||||||
|
{
|
||||||
|
CURL * curl = curl_easy_init();
|
||||||
|
struct curl_slist * slist = NULL;
|
||||||
|
if (headers) {
|
||||||
|
this->appendHeaders(*headers, &slist);
|
||||||
|
}
|
||||||
|
if (params) {
|
||||||
|
this->appendUrlParams(*params, &url);
|
||||||
|
}
|
||||||
|
|
||||||
|
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
|
||||||
|
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, onWriteData);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *) response);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, true);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT_MS, this->connect_timeout);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, this->socket_timeout);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_VERBOSE, this->debug);
|
||||||
|
|
||||||
|
int status_code = curl_easy_perform(curl);
|
||||||
|
|
||||||
|
curl_easy_cleanup(curl);
|
||||||
|
curl_slist_free_all(slist);
|
||||||
|
|
||||||
|
return status_code;
|
||||||
|
}
|
||||||
|
|
||||||
|
int post(
|
||||||
|
std::string url,
|
||||||
|
std::map<std::string, std::string> const * params,
|
||||||
|
const std::string & body,
|
||||||
|
std::map<std::string, std::string> const * headers,
|
||||||
|
std::string * response) const
|
||||||
|
{
|
||||||
|
struct curl_slist * slist = NULL;
|
||||||
|
CURL * curl = curl_easy_init();
|
||||||
|
if (headers) {
|
||||||
|
this->appendHeaders(*headers, &slist);
|
||||||
|
}
|
||||||
|
if (params) {
|
||||||
|
this->appendUrlParams(*params, &url);
|
||||||
|
}
|
||||||
|
|
||||||
|
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
|
||||||
|
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_POST, true);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body.c_str());
|
||||||
|
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, body.size());
|
||||||
|
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, onWriteData);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *) response);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, true);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT_MS, this->connect_timeout);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, this->socket_timeout);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_VERBOSE, this->debug);
|
||||||
|
|
||||||
|
int status_code = curl_easy_perform(curl);
|
||||||
|
|
||||||
|
curl_easy_cleanup(curl);
|
||||||
|
curl_slist_free_all(slist);
|
||||||
|
|
||||||
|
return status_code;
|
||||||
|
}
|
||||||
|
|
||||||
|
int post(
|
||||||
|
std::string url,
|
||||||
|
std::map<std::string, std::string> const * params,
|
||||||
|
std::map<std::string, std::string> const & data,
|
||||||
|
std::map<std::string, std::string> const * headers,
|
||||||
|
std::string * response) const
|
||||||
|
{
|
||||||
|
|
||||||
|
std::string body;
|
||||||
|
this->makeUrlencodedForm(data, &body);
|
||||||
|
return this->post(std::move(url), params, body, headers, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
int post(
|
||||||
|
std::string url,
|
||||||
|
std::map<std::string, std::string> const * params,
|
||||||
|
Json::Value const & data,
|
||||||
|
std::map<std::string, std::string> const * headers,
|
||||||
|
std::string * response) const
|
||||||
|
{
|
||||||
|
std::string body;
|
||||||
|
Json::StreamWriterBuilder swb;
|
||||||
|
std::unique_ptr<Json::StreamWriter> writer(swb.newStreamWriter());
|
||||||
|
std::ostringstream os;
|
||||||
|
writer->write(data, &os);
|
||||||
|
body = os.str();
|
||||||
|
std::map<std::string, std::string> temp_headers;
|
||||||
|
if (headers) {
|
||||||
|
std::map<std::string, std::string> temp_headers(*headers);
|
||||||
|
}
|
||||||
|
|
||||||
|
temp_headers["Content-Type"] = "application/json";
|
||||||
|
return this->post(url.c_str(), params, body, &temp_headers, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int post(
|
||||||
|
std::string url,
|
||||||
|
std::map<std::string, std::string> const * params,
|
||||||
|
std::map<std::string, std::string> const * headers,
|
||||||
|
std::string * response) const
|
||||||
|
{
|
||||||
|
const static std::string EMPTY_STRING;
|
||||||
|
return this->post(std::move(url), params, EMPTY_STRING, headers, response);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,283 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2017 Baidu.com, Inc. All Rights Reserved
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||||
|
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations under the License.
|
||||||
|
*
|
||||||
|
* @author baidu aip
|
||||||
|
*/
|
||||||
|
#ifndef __AIP_UTILS_H__
|
||||||
|
#define __AIP_UTILS_H__
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <fstream>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <openssl/evp.h>
|
||||||
|
#include <openssl/hmac.h>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <openssl/md5.h>
|
||||||
|
|
||||||
|
const int __BCE_VERSION__ = 1;
|
||||||
|
const int __BCE_EXPIRE__ = 1800;
|
||||||
|
|
||||||
|
namespace aip {
|
||||||
|
|
||||||
|
template<class CharT, class Traits, class Allocator>
|
||||||
|
std::basic_istream<CharT, Traits>& getall(std::basic_istream<CharT, Traits>& input,
|
||||||
|
std::basic_string<CharT, Traits, Allocator>& str) {
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << input.rdbuf();
|
||||||
|
str.assign(oss.str());
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int get_file_content(const char *filename, std::string* out) {
|
||||||
|
std::ifstream in(filename, std::ios::in | std::ios::binary);
|
||||||
|
if (in) {
|
||||||
|
getall(in, *out);
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::string to_upper(std::string src)
|
||||||
|
{
|
||||||
|
std::transform(src.begin(), src.end(), src.begin(), toupper);
|
||||||
|
return src;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline std::string to_lower(std::string src)
|
||||||
|
{
|
||||||
|
std::transform(src.begin(), src.end(), src.begin(), tolower);
|
||||||
|
return src;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::string to_hex(unsigned char c, bool lower = false)
|
||||||
|
{
|
||||||
|
const std::string hex = "0123456789ABCDEF";
|
||||||
|
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << hex[c >> 4] << hex[c & 0xf];
|
||||||
|
|
||||||
|
return lower ? to_lower(ss.str()) : ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline time_t now()
|
||||||
|
{
|
||||||
|
return time(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string utc_time(time_t timestamp)
|
||||||
|
{
|
||||||
|
struct tm result_tm;
|
||||||
|
char buffer[32];
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
gmtime_s(&result_tm, ×tamp);
|
||||||
|
#else
|
||||||
|
gmtime_r(×tamp, &result_tm);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
size_t size = strftime(buffer, 32, "%Y-%m-%dT%H:%M:%SZ", &result_tm);
|
||||||
|
|
||||||
|
return std::string(buffer, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void url_parse(
|
||||||
|
const std::string & url,
|
||||||
|
std::map<std::string, std::string> & params)
|
||||||
|
{
|
||||||
|
int pos = (int)url.find("?");
|
||||||
|
if (pos != -1)
|
||||||
|
{
|
||||||
|
int key_start = pos + 1,
|
||||||
|
key_len = 0,
|
||||||
|
val_start = 0;
|
||||||
|
for (int i = key_start; i <= (int)url.size(); ++i)
|
||||||
|
{
|
||||||
|
switch (url[i])
|
||||||
|
{
|
||||||
|
case '=':
|
||||||
|
key_len = i - key_start;
|
||||||
|
val_start = i + 1;
|
||||||
|
break;
|
||||||
|
case '\0':
|
||||||
|
case '&':
|
||||||
|
if (key_len != 0)
|
||||||
|
{
|
||||||
|
params[url.substr(key_start, key_len)] = url.substr(val_start, i - val_start);
|
||||||
|
key_start = i + 1;
|
||||||
|
key_len = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string url_encode(const std::string & input, bool encode_slash=true)
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
const char *str = input.c_str();
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < input.size(); i++)
|
||||||
|
{
|
||||||
|
unsigned char c = str[i];
|
||||||
|
if (isalnum(c) || c == '_' || c == '-' || c == '~' || c == '.' || (!encode_slash && c == '/'))
|
||||||
|
{
|
||||||
|
ss << c;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ss << "%" << to_hex(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string canonicalize_params(std::map<std::string, std::string> & params)
|
||||||
|
{
|
||||||
|
std::vector<std::string> v;
|
||||||
|
v.reserve(params.size());
|
||||||
|
|
||||||
|
for (auto & it : params) {
|
||||||
|
v.push_back(url_encode(it.first) + "=" + url_encode(it.second));
|
||||||
|
}
|
||||||
|
std::sort(v.begin(), v.end());
|
||||||
|
|
||||||
|
std::string result;
|
||||||
|
for (auto & it : v)
|
||||||
|
{
|
||||||
|
result.append((result.empty() ? "" : "&") + it);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string canonicalize_headers(std::map<std::string, std::string> & headers)
|
||||||
|
{
|
||||||
|
std::vector<std::string> v;
|
||||||
|
v.reserve(headers.size());
|
||||||
|
|
||||||
|
for (auto & it : headers) {
|
||||||
|
v.push_back(url_encode(to_lower(it.first)) + ":" + url_encode(it.second));
|
||||||
|
}
|
||||||
|
std::sort(v.begin(), v.end());
|
||||||
|
|
||||||
|
std::string result;
|
||||||
|
for (auto & it : v)
|
||||||
|
{
|
||||||
|
result.append((result.empty() ? "" : "\n") + it);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string get_headers_keys(std::map<std::string, std::string> & headers)
|
||||||
|
{
|
||||||
|
std::vector<std::string> v;
|
||||||
|
v.reserve(headers.size());
|
||||||
|
|
||||||
|
for (auto & it : headers) {
|
||||||
|
v.push_back(to_lower(it.first));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string result;
|
||||||
|
for (auto & it : v)
|
||||||
|
{
|
||||||
|
result.append((result.empty() ? "" : ";") + it);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string get_host(const std::string & url)
|
||||||
|
{
|
||||||
|
int pos = (int)url.find("://") + 3;
|
||||||
|
return url.substr(
|
||||||
|
pos,
|
||||||
|
url.find('/', pos) - pos
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::string get_path(const std::string & url)
|
||||||
|
{
|
||||||
|
int path_start = (int)url.find('/', url.find("://") + 3);
|
||||||
|
int path_end = (int)url.find('?');
|
||||||
|
path_end = path_end == -1 ? (int)url.size() : path_end;
|
||||||
|
|
||||||
|
return url.substr(path_start, path_end - path_start);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string hmac_sha256(
|
||||||
|
const std::string & src,
|
||||||
|
const std::string & sk)
|
||||||
|
{
|
||||||
|
const EVP_MD *evp_md = EVP_sha256();
|
||||||
|
unsigned char md[EVP_MAX_MD_SIZE];
|
||||||
|
unsigned int md_len = 0;
|
||||||
|
|
||||||
|
if (HMAC(evp_md,
|
||||||
|
reinterpret_cast<const unsigned char *>(sk.data()), (int)sk.size(),
|
||||||
|
reinterpret_cast<const unsigned char *>(src.data()), src.size(),
|
||||||
|
md, &md_len) == NULL)
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::stringstream ss;
|
||||||
|
for (int i = 0; i < (int)md_len; ++i)
|
||||||
|
{
|
||||||
|
ss << to_hex(md[i], true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
void sign(
|
||||||
|
std::string method,
|
||||||
|
std::string & url,
|
||||||
|
std::map<std::string, std::string> & params,
|
||||||
|
std::map<std::string, std::string> & headers,
|
||||||
|
std::string & ak,
|
||||||
|
std::string & sk)
|
||||||
|
{
|
||||||
|
url_parse(url, params);
|
||||||
|
headers["Host"] = get_host(url);
|
||||||
|
std::string timestamp = utc_time(now());
|
||||||
|
headers["x-bce-date"] = timestamp;
|
||||||
|
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << "bce-auth-v" << __BCE_VERSION__ << "/" << ak << "/"
|
||||||
|
<< timestamp << "/" << __BCE_EXPIRE__;
|
||||||
|
|
||||||
|
std::string val = ss.str();
|
||||||
|
std::string sign_key = hmac_sha256(val, sk);
|
||||||
|
|
||||||
|
ss.str("");
|
||||||
|
ss << to_upper(method) << '\n' << url_encode(get_path(url), false)
|
||||||
|
<< '\n' << canonicalize_params(params)
|
||||||
|
<< '\n' << canonicalize_headers(headers);
|
||||||
|
|
||||||
|
std::string signature = hmac_sha256(ss.str(), sign_key);
|
||||||
|
|
||||||
|
ss.str("");
|
||||||
|
ss << "bce-auth-v" << __BCE_VERSION__ << "/" << ak << "/"
|
||||||
|
<< timestamp << "/" << __BCE_EXPIRE__ << "/"
|
||||||
|
<< get_headers_keys(headers) << "/" << signature;
|
||||||
|
|
||||||
|
headers["authorization"] = ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include "ocr.h" // 用于调用接口
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
int main(int argc, char const *argv[])
|
||||||
|
{
|
||||||
|
if (argc < 2)
|
||||||
|
{
|
||||||
|
cout << "用法: " << argv[0] << " 驾驶证照片" << endl;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
string app_id = "35475147"; // 你的 App ID
|
||||||
|
string api_key = "CSneGCoRs8zMD1F1PPnXyzPP"; // 你的 Api Key
|
||||||
|
string secret_key = "wlKjVS2lE9xPFVV7G5EI3gYm7Zk3tnu1"; // 你的 Secret Key
|
||||||
|
|
||||||
|
aip::Ocr client(app_id, api_key, secret_key); // 新建一个对象, 用于调用接口, 调用通用文字识别, 图片参数为本地图片
|
||||||
|
// cout << "ok" << endl;
|
||||||
|
|
||||||
|
// 定义 json 格式的数据类型 Value, result 是 json 类型的 Value 类实例, 用于存储返回的结果
|
||||||
|
Json::Value result;
|
||||||
|
string image;
|
||||||
|
|
||||||
|
// 加载本地的驾驶证图片内容到 image 对象中, 用于调用驾驶证识别
|
||||||
|
aip::get_file_content(argv[1], &image);
|
||||||
|
|
||||||
|
// 客户端发送图片内容到百度服务器, 并返回结果到 result 对象中
|
||||||
|
result = client.driving_license(image, aip::null);
|
||||||
|
cout << "识别到的驾驶证信息如下: " << endl;
|
||||||
|
// cout << result << endl;
|
||||||
|
cout << "姓名: " << result["words_result"]["姓名"]["words"].asString() << endl;
|
||||||
|
cout << "出生日期: " << result["words_result"]["出生日期"]["words"].asString() << endl;
|
||||||
|
cout << "证号: " << result["words_result"]["证号"]["words"].asString() << endl;
|
||||||
|
cout << "住址: " << result["words_result"]["住址"]["words"].asString() << endl;
|
||||||
|
cout << "发证单位: " << result["words_result"]["发证单位"]["words"].asString() << endl;
|
||||||
|
cout << "初次领证日期: " << result["words_result"]["初次领证日期"]["words"].asString() << endl;
|
||||||
|
cout << "国籍: " << result["words_result"]["国籍"]["words"].asString() << endl;
|
||||||
|
cout << "准驾车型: " << result["words_result"]["准驾车型"]["words"].asString() << endl;
|
||||||
|
cout << "性别: " << result["words_result"]["性别"]["words"].asString() << endl;
|
||||||
|
cout << "有效期限: " << result["words_result"]["有效期限"]["words"].asString() << " 至 " << result["words_result"]["至"]["words"].asString() << endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include "ocr.h" // 用于调用接口
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
int main(int argc, char const *argv[])
|
||||||
|
{
|
||||||
|
if (argc < 2)
|
||||||
|
{
|
||||||
|
cout << "用法: " << argv[0] << " 身份证照片" << endl;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
string app_id = "35475147"; // 你的 App ID
|
||||||
|
string api_key = "CSneGCoRs8zMD1F1PPnXyzPP"; // 你的 Api Key
|
||||||
|
string secret_key = "wlKjVS2lE9xPFVV7G5EI3gYm7Zk3tnu1"; // 你的 Secret Key
|
||||||
|
|
||||||
|
aip::Ocr client(app_id, api_key, secret_key); // 新建一个对象, 用于调用接口, 调用通用文字识别, 图片参数为本地图片
|
||||||
|
// cout << "ok" << endl;
|
||||||
|
|
||||||
|
// 定义 json 格式的数据类型 Value, result 是 json 类型的 Value 类实例, 用于存储返回的结果
|
||||||
|
Json::Value result;
|
||||||
|
string image;
|
||||||
|
|
||||||
|
// 加载本地的身份证图片内容到 image 对象中, 用于调用身份证识别
|
||||||
|
aip::get_file_content(argv[1], &image);
|
||||||
|
|
||||||
|
// 客户端发送图片内容到百度服务器, 并返回结果到 result 对象中
|
||||||
|
result = client.idcard(image, "front", aip::null); // front: 正面, back: 背面
|
||||||
|
|
||||||
|
cout << "识别到的身份证信息如下: " << endl;
|
||||||
|
cout << "姓名: " << result["words_result"]["姓名"]["words"].asString() << endl;
|
||||||
|
cout << "性别: " << result["words_result"]["性别"]["words"].asString() << endl;
|
||||||
|
cout << "民族: " << result["words_result"]["民族"]["words"].asString() << endl;
|
||||||
|
cout << "出生: " << result["words_result"]["出生"]["words"].asString() << endl;
|
||||||
|
cout << "住址: " << result["words_result"]["住址"]["words"].asString() << endl;
|
||||||
|
cout << "公民身份号码: " << result["words_result"]["公民身份号码"]["words"].asString() << endl;
|
||||||
|
// cout << "-------------------------" << endl;
|
||||||
|
// cout << result << endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 78 KiB |
|
After Width: | Height: | Size: 260 KiB |
|
After Width: | Height: | Size: 124 KiB |
|
After Width: | Height: | Size: 166 KiB |
|
After Width: | Height: | Size: 1.3 MiB |
|
After Width: | Height: | Size: 147 KiB |
|
After Width: | Height: | Size: 1.2 MiB |
@@ -0,0 +1,17 @@
|
|||||||
|
cc = g++
|
||||||
|
cflags = -Wall -lssl -lcrypto -lcurl -ljsoncpp
|
||||||
|
cflags += -I/home/flykhan/.tools/openssl_build/include/
|
||||||
|
cflags += -I/home/flykhan/.tools/curl/include/
|
||||||
|
cflags += -I/home/flykhan/.tools/jsoncpp-Sandbox/jsoncpp-build/include/
|
||||||
|
cflags += -L/home/flykhan/.tools/openssl_build/lib/
|
||||||
|
cflags += -L/home/flykhan/.tools/curl/lib/
|
||||||
|
cflags += -L/home/flykhan/.tools/jsoncpp-Sandbox/jsoncpp-build/lib/
|
||||||
|
|
||||||
|
main:
|
||||||
|
$(cc) main.cpp -o main $(cflags) -std=c++14
|
||||||
|
|
||||||
|
jsonTypeShow:
|
||||||
|
$(cc) jsonTypeShow.cpp -o jsonTypeShow $(cflags) -std=c++14
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm *.o main jsonTypeShow -rf
|
||||||
|
After Width: | Height: | Size: 502 KiB |
@@ -0,0 +1,264 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2017 Baidu.com, Inc. All Rights Reserved
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||||
|
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations under the License.
|
||||||
|
*
|
||||||
|
* @author baidu aip
|
||||||
|
*/
|
||||||
|
#ifndef __AIP_BASE_H__
|
||||||
|
#define __AIP_BASE_H__
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <cstring>
|
||||||
|
#include "http.h"
|
||||||
|
#include "json/json.h"
|
||||||
|
#include "base64.h"
|
||||||
|
#include "curl/curl.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
namespace aip {
|
||||||
|
|
||||||
|
static const char* AIP_SDK_VERSION = "0.3.3";
|
||||||
|
static const char* CURL_ERROR_CODE = "curl_error_code";
|
||||||
|
static const std::string ACCESS_TOKEN_URL = "https://aip.baidubce.com/oauth/2.0/token";
|
||||||
|
static const std::map<std::string, std::string> null;
|
||||||
|
|
||||||
|
class AipBase
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
std::string _app_id;
|
||||||
|
int _expired_time;
|
||||||
|
bool _is_bce;
|
||||||
|
bool _has_decide_type;
|
||||||
|
std::string _scope;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::string getAccessToken()
|
||||||
|
{
|
||||||
|
time_t now = time(NULL);
|
||||||
|
if (!access_token.empty())
|
||||||
|
{
|
||||||
|
return this->access_token;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (now < this->_expired_time - 60 * 60 * 24)
|
||||||
|
{
|
||||||
|
return this->access_token;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string response;
|
||||||
|
std::map<std::string, std::string> params;
|
||||||
|
|
||||||
|
params["grant_type"] = "client_credentials";
|
||||||
|
params["client_id"] = this->ak;
|
||||||
|
params["client_secret"] = this->sk;
|
||||||
|
int status_code = this->client.get(
|
||||||
|
ACCESS_TOKEN_URL,
|
||||||
|
¶ms,
|
||||||
|
nullptr,
|
||||||
|
&response
|
||||||
|
);
|
||||||
|
Json::Value obj;
|
||||||
|
if (status_code != CURLcode::CURLE_OK) {
|
||||||
|
obj[CURL_ERROR_CODE] = status_code;
|
||||||
|
return obj.toStyledString();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string error;
|
||||||
|
std::unique_ptr<Json::CharReader> reader(crbuilder.newCharReader());
|
||||||
|
reader->parse(response.data(), response.data() + response.size(), &obj, &error);
|
||||||
|
this->access_token = obj["access_token"].asString();
|
||||||
|
this->_expired_time = obj["expires_in"].asInt() + (int) now;
|
||||||
|
this->_scope = obj["scope"].asString();
|
||||||
|
return this->access_token;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
std::string ak;
|
||||||
|
std::string sk;
|
||||||
|
HttpClient client;
|
||||||
|
Json::CharReaderBuilder crbuilder;
|
||||||
|
std::string access_token;
|
||||||
|
AipBase(const std::string & app_id, const std::string & ak, const std::string & sk):
|
||||||
|
_app_id(app_id),
|
||||||
|
_is_bce(false),
|
||||||
|
_has_decide_type(false),
|
||||||
|
ak(ak),
|
||||||
|
sk(sk)
|
||||||
|
{
|
||||||
|
if (_app_id == "")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setConnectionTimeoutInMillis(int connect_timeout)
|
||||||
|
{
|
||||||
|
this->client.setConnectTimeout(connect_timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setSocketTimeoutInMillis(int socket_timeout)
|
||||||
|
{
|
||||||
|
this->client.setSocketTimeout(socket_timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setDebug(bool debug)
|
||||||
|
{
|
||||||
|
this->client.setDebug(debug);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string getAk() {
|
||||||
|
return ak;
|
||||||
|
}
|
||||||
|
|
||||||
|
Json::Value request(
|
||||||
|
std::string url,
|
||||||
|
std::map<std::string, std::string> const & params,
|
||||||
|
std::string const & data,
|
||||||
|
std::map<std::string, std::string> const & headers)
|
||||||
|
{
|
||||||
|
std::string response;
|
||||||
|
Json::Value obj;
|
||||||
|
std::string body;
|
||||||
|
auto headers_for_sign = headers;
|
||||||
|
|
||||||
|
auto temp_params = params;
|
||||||
|
|
||||||
|
temp_params["charset"] = "UTF-8";
|
||||||
|
|
||||||
|
this->prepare_request(url, temp_params, headers_for_sign);
|
||||||
|
|
||||||
|
int status_code = this->client.post(url, &temp_params, data, &headers_for_sign, &response);
|
||||||
|
|
||||||
|
if (status_code != CURLcode::CURLE_OK) {
|
||||||
|
obj[CURL_ERROR_CODE] = status_code;
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string error;
|
||||||
|
std::unique_ptr<Json::CharReader> reader(crbuilder.newCharReader());
|
||||||
|
reader->parse(response.data(), response.data() + response.size(), &obj, &error);
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
Json::Value request(
|
||||||
|
std::string url,
|
||||||
|
std::map<std::string, std::string> const & params,
|
||||||
|
std::map<std::string, std::string> const & data,
|
||||||
|
std::map<std::string, std::string> const & headers)
|
||||||
|
{
|
||||||
|
std::string response;
|
||||||
|
Json::Value obj;
|
||||||
|
|
||||||
|
auto headers_for_sign = headers;
|
||||||
|
auto temp_params = params;
|
||||||
|
|
||||||
|
this->prepare_request(url, temp_params, headers_for_sign);
|
||||||
|
|
||||||
|
int status_code = this->client.post(url, &temp_params, data, &headers_for_sign, &response);
|
||||||
|
|
||||||
|
if (status_code != CURLcode::CURLE_OK) {
|
||||||
|
obj[CURL_ERROR_CODE] = status_code;
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string error;
|
||||||
|
std::unique_ptr<Json::CharReader> reader(crbuilder.newCharReader());
|
||||||
|
reader->parse(response.data(), response.data() + response.size(), &obj, &error);
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
void prepare_request(std::string url,
|
||||||
|
std::map<std::string, std::string> & params,
|
||||||
|
std::map<std::string, std::string> & headers)
|
||||||
|
{
|
||||||
|
|
||||||
|
params["aipSdk"] = "C";
|
||||||
|
params["aipSdkVersion"] = AIP_SDK_VERSION;
|
||||||
|
|
||||||
|
if (_has_decide_type) {
|
||||||
|
if (_is_bce) {
|
||||||
|
std::string method = "POST";
|
||||||
|
sign(method, url, params, headers, ak, sk);
|
||||||
|
} else {
|
||||||
|
params["access_token"] = this->getAccessToken();
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getAccessToken() == "") {
|
||||||
|
_is_bce = true;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
const char * t = std::strstr(this->_scope.c_str(), "brain_all_scope");
|
||||||
|
|
||||||
|
if (t == NULL)
|
||||||
|
{
|
||||||
|
_is_bce = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_has_decide_type = true;
|
||||||
|
prepare_request(url, params, headers);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Json::Value requestjson(
|
||||||
|
std::string url,
|
||||||
|
Json::Value & data,
|
||||||
|
std::map<std::string, std::string> & params,
|
||||||
|
std::map<std::string, std::string> const & headers)
|
||||||
|
{
|
||||||
|
|
||||||
|
std::string response;
|
||||||
|
Json::Value obj;
|
||||||
|
auto headers_for_sign = headers;
|
||||||
|
auto temp_params = params;
|
||||||
|
this->prepare_request(url, temp_params, headers_for_sign);
|
||||||
|
int status_code = this->client.post(url, nullptr, data, nullptr, &response);
|
||||||
|
if (status_code != CURLcode::CURLE_OK) {
|
||||||
|
obj[aip::CURL_ERROR_CODE] = status_code;
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string error;
|
||||||
|
std::unique_ptr<Json::CharReader> reader(crbuilder.newCharReader());
|
||||||
|
reader->parse(response.data(), response.data() + response.size(), &obj, &error);
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
Json::Value request_com(
|
||||||
|
std::string const & url,
|
||||||
|
Json::Value & data)
|
||||||
|
{
|
||||||
|
std::string response;
|
||||||
|
Json::Value obj;
|
||||||
|
int status_code = this->client.post(url, nullptr, data, nullptr, &response);
|
||||||
|
|
||||||
|
if (status_code != CURLcode::CURLE_OK) {
|
||||||
|
obj[aip::CURL_ERROR_CODE] = status_code;
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
std::string error;
|
||||||
|
std::unique_ptr<Json::CharReader> reader(crbuilder.newCharReader());
|
||||||
|
reader->parse(response.data(), response.data() + response.size(), &obj, &error);
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,130 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2017 Baidu.com, Inc. All Rights Reserved
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||||
|
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations under the License.
|
||||||
|
*
|
||||||
|
* @author baidu aip
|
||||||
|
*/
|
||||||
|
#ifndef __AIP_BASE64_H__
|
||||||
|
#define __AIP_BASE64_H__
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace aip {
|
||||||
|
|
||||||
|
static const std::string base64_chars =
|
||||||
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||||
|
"abcdefghijklmnopqrstuvwxyz"
|
||||||
|
"0123456789+/";
|
||||||
|
|
||||||
|
|
||||||
|
static inline bool is_base64(const char c)
|
||||||
|
{
|
||||||
|
return (isalnum(c) || (c == '+') || (c == '/'));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string base64_encode(const char * bytes_to_encode, unsigned int in_len)
|
||||||
|
{
|
||||||
|
std::string ret;
|
||||||
|
int i = 0;
|
||||||
|
int j = 0;
|
||||||
|
unsigned char char_array_3[3];
|
||||||
|
unsigned char char_array_4[4];
|
||||||
|
|
||||||
|
while (in_len--)
|
||||||
|
{
|
||||||
|
char_array_3[i++] = *(bytes_to_encode++);
|
||||||
|
if(i == 3)
|
||||||
|
{
|
||||||
|
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
|
||||||
|
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
|
||||||
|
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
|
||||||
|
char_array_4[3] = char_array_3[2] & 0x3f;
|
||||||
|
|
||||||
|
for(i = 0; (i <4) ; i++)
|
||||||
|
{
|
||||||
|
ret += base64_chars[char_array_4[i]];
|
||||||
|
}
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(i)
|
||||||
|
{
|
||||||
|
for(j = i; j < 3; j++)
|
||||||
|
{
|
||||||
|
char_array_3[j] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
|
||||||
|
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
|
||||||
|
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
|
||||||
|
char_array_4[3] = char_array_3[2] & 0x3f;
|
||||||
|
|
||||||
|
for(j = 0; (j < i + 1); j++)
|
||||||
|
{
|
||||||
|
ret += base64_chars[char_array_4[j]];
|
||||||
|
}
|
||||||
|
|
||||||
|
while((i++ < 3))
|
||||||
|
{
|
||||||
|
ret += '=';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string base64_decode(std::string const & encoded_string)
|
||||||
|
{
|
||||||
|
int in_len = (int) encoded_string.size();
|
||||||
|
int i = 0;
|
||||||
|
int j = 0;
|
||||||
|
int in_ = 0;
|
||||||
|
unsigned char char_array_4[4], char_array_3[3];
|
||||||
|
std::string ret;
|
||||||
|
|
||||||
|
while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
|
||||||
|
char_array_4[i++] = encoded_string[in_]; in_++;
|
||||||
|
if (i ==4) {
|
||||||
|
for (i = 0; i <4; i++)
|
||||||
|
char_array_4[i] = base64_chars.find(char_array_4[i]);
|
||||||
|
|
||||||
|
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
|
||||||
|
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
|
||||||
|
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
|
||||||
|
|
||||||
|
for (i = 0; (i < 3); i++)
|
||||||
|
ret += char_array_3[i];
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i) {
|
||||||
|
for (j = i; j <4; j++)
|
||||||
|
char_array_4[j] = 0;
|
||||||
|
|
||||||
|
for (j = 0; j <4; j++)
|
||||||
|
char_array_4[j] = base64_chars.find(char_array_4[j]);
|
||||||
|
|
||||||
|
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
|
||||||
|
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
|
||||||
|
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
|
||||||
|
|
||||||
|
for (j = 0; (j < i - 1); j++) ret += char_array_3[j];
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,234 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2017 Baidu.com, Inc. All Rights Reserved
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||||
|
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations under the License.
|
||||||
|
*
|
||||||
|
* @author baidu aip
|
||||||
|
*/
|
||||||
|
#ifndef __AIP_HTTP_H__
|
||||||
|
#define __AIP_HTTP_H__
|
||||||
|
|
||||||
|
#include "curl/curl.h"
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
|
#include <map>
|
||||||
|
#include <json/json.h>
|
||||||
|
|
||||||
|
namespace aip {
|
||||||
|
|
||||||
|
inline size_t onWriteData(void * buffer, size_t size, size_t nmemb, void * userp)
|
||||||
|
{
|
||||||
|
std::string * str = dynamic_cast<std::string *>((std::string *)userp);
|
||||||
|
str->append((char *)buffer, size * nmemb);
|
||||||
|
return nmemb;
|
||||||
|
}
|
||||||
|
|
||||||
|
class HttpClient
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
bool debug = false;
|
||||||
|
int connect_timeout = 10000;
|
||||||
|
int socket_timeout = 10000;
|
||||||
|
|
||||||
|
void makeUrlencodedForm(std::map<std::string, std::string> const & params, std::string * content) const
|
||||||
|
{
|
||||||
|
content->clear();
|
||||||
|
std::map<std::string, std::string>::const_iterator it;
|
||||||
|
for(it=params.begin(); it!=params.end(); it++)
|
||||||
|
{
|
||||||
|
char * key = curl_escape(it->first.c_str(), (int) it->first.size());
|
||||||
|
char * value = curl_escape(it->second.c_str(),(int) it->second.size());
|
||||||
|
*content += key;
|
||||||
|
*content += '=';
|
||||||
|
*content += value;
|
||||||
|
*content += '&';
|
||||||
|
curl_free(key);
|
||||||
|
curl_free(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void appendUrlParams(std::map<std::string, std::string> const & params, std::string* url) const
|
||||||
|
{
|
||||||
|
if(params.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
std::string content;
|
||||||
|
this->makeUrlencodedForm(params, &content);
|
||||||
|
bool url_has_param = false;
|
||||||
|
for (const auto& ch : *url) {
|
||||||
|
if (ch == '?') {
|
||||||
|
url_has_param = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (url_has_param) {
|
||||||
|
url->append("&");
|
||||||
|
} else {
|
||||||
|
url->append("?");
|
||||||
|
}
|
||||||
|
url->append(content);
|
||||||
|
}
|
||||||
|
|
||||||
|
void appendHeaders(std::map<std::string, std::string> const & headers, curl_slist ** slist) const
|
||||||
|
{
|
||||||
|
std::ostringstream ostr;
|
||||||
|
std::map<std::string, std::string>::const_iterator it;
|
||||||
|
for(it=headers.begin(); it!=headers.end(); it++)
|
||||||
|
{
|
||||||
|
ostr << it->first << ":" << it->second;
|
||||||
|
*slist = curl_slist_append(*slist, ostr.str().c_str());
|
||||||
|
ostr.str("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
HttpClient() = default;
|
||||||
|
|
||||||
|
HttpClient(const HttpClient &) = delete;
|
||||||
|
HttpClient & operator=(const HttpClient &) = delete;
|
||||||
|
|
||||||
|
void setConnectTimeout(int connect_timeout)
|
||||||
|
{
|
||||||
|
this->connect_timeout = connect_timeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setSocketTimeout(int socket_timeout)
|
||||||
|
{
|
||||||
|
this->socket_timeout = socket_timeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setDebug(bool debug)
|
||||||
|
{
|
||||||
|
this->debug = debug;
|
||||||
|
}
|
||||||
|
|
||||||
|
int get(
|
||||||
|
std::string url,
|
||||||
|
std::map<std::string, std::string> const * params,
|
||||||
|
std::map<std::string, std::string> const * headers,
|
||||||
|
std::string * response) const
|
||||||
|
{
|
||||||
|
CURL * curl = curl_easy_init();
|
||||||
|
struct curl_slist * slist = NULL;
|
||||||
|
if (headers) {
|
||||||
|
this->appendHeaders(*headers, &slist);
|
||||||
|
}
|
||||||
|
if (params) {
|
||||||
|
this->appendUrlParams(*params, &url);
|
||||||
|
}
|
||||||
|
|
||||||
|
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
|
||||||
|
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, onWriteData);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *) response);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, true);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT_MS, this->connect_timeout);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, this->socket_timeout);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_VERBOSE, this->debug);
|
||||||
|
|
||||||
|
int status_code = curl_easy_perform(curl);
|
||||||
|
|
||||||
|
curl_easy_cleanup(curl);
|
||||||
|
curl_slist_free_all(slist);
|
||||||
|
|
||||||
|
return status_code;
|
||||||
|
}
|
||||||
|
|
||||||
|
int post(
|
||||||
|
std::string url,
|
||||||
|
std::map<std::string, std::string> const * params,
|
||||||
|
const std::string & body,
|
||||||
|
std::map<std::string, std::string> const * headers,
|
||||||
|
std::string * response) const
|
||||||
|
{
|
||||||
|
struct curl_slist * slist = NULL;
|
||||||
|
CURL * curl = curl_easy_init();
|
||||||
|
if (headers) {
|
||||||
|
this->appendHeaders(*headers, &slist);
|
||||||
|
}
|
||||||
|
if (params) {
|
||||||
|
this->appendUrlParams(*params, &url);
|
||||||
|
}
|
||||||
|
|
||||||
|
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
|
||||||
|
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_POST, true);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body.c_str());
|
||||||
|
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, body.size());
|
||||||
|
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, onWriteData);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *) response);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, true);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT_MS, this->connect_timeout);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, this->socket_timeout);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_VERBOSE, this->debug);
|
||||||
|
|
||||||
|
int status_code = curl_easy_perform(curl);
|
||||||
|
|
||||||
|
curl_easy_cleanup(curl);
|
||||||
|
curl_slist_free_all(slist);
|
||||||
|
|
||||||
|
return status_code;
|
||||||
|
}
|
||||||
|
|
||||||
|
int post(
|
||||||
|
std::string url,
|
||||||
|
std::map<std::string, std::string> const * params,
|
||||||
|
std::map<std::string, std::string> const & data,
|
||||||
|
std::map<std::string, std::string> const * headers,
|
||||||
|
std::string * response) const
|
||||||
|
{
|
||||||
|
|
||||||
|
std::string body;
|
||||||
|
this->makeUrlencodedForm(data, &body);
|
||||||
|
return this->post(std::move(url), params, body, headers, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
int post(
|
||||||
|
std::string url,
|
||||||
|
std::map<std::string, std::string> const * params,
|
||||||
|
Json::Value const & data,
|
||||||
|
std::map<std::string, std::string> const * headers,
|
||||||
|
std::string * response) const
|
||||||
|
{
|
||||||
|
std::string body;
|
||||||
|
Json::StreamWriterBuilder swb;
|
||||||
|
std::unique_ptr<Json::StreamWriter> writer(swb.newStreamWriter());
|
||||||
|
std::ostringstream os;
|
||||||
|
writer->write(data, &os);
|
||||||
|
body = os.str();
|
||||||
|
std::map<std::string, std::string> temp_headers;
|
||||||
|
if (headers) {
|
||||||
|
std::map<std::string, std::string> temp_headers(*headers);
|
||||||
|
}
|
||||||
|
|
||||||
|
temp_headers["Content-Type"] = "application/json";
|
||||||
|
return this->post(url.c_str(), params, body, &temp_headers, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int post(
|
||||||
|
std::string url,
|
||||||
|
std::map<std::string, std::string> const * params,
|
||||||
|
std::map<std::string, std::string> const * headers,
|
||||||
|
std::string * response) const
|
||||||
|
{
|
||||||
|
const static std::string EMPTY_STRING;
|
||||||
|
return this->post(std::move(url), params, EMPTY_STRING, headers, response);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,283 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2017 Baidu.com, Inc. All Rights Reserved
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||||
|
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations under the License.
|
||||||
|
*
|
||||||
|
* @author baidu aip
|
||||||
|
*/
|
||||||
|
#ifndef __AIP_UTILS_H__
|
||||||
|
#define __AIP_UTILS_H__
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <fstream>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <openssl/evp.h>
|
||||||
|
#include <openssl/hmac.h>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <openssl/md5.h>
|
||||||
|
|
||||||
|
const int __BCE_VERSION__ = 1;
|
||||||
|
const int __BCE_EXPIRE__ = 1800;
|
||||||
|
|
||||||
|
namespace aip {
|
||||||
|
|
||||||
|
template<class CharT, class Traits, class Allocator>
|
||||||
|
std::basic_istream<CharT, Traits>& getall(std::basic_istream<CharT, Traits>& input,
|
||||||
|
std::basic_string<CharT, Traits, Allocator>& str) {
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << input.rdbuf();
|
||||||
|
str.assign(oss.str());
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int get_file_content(const char *filename, std::string* out) {
|
||||||
|
std::ifstream in(filename, std::ios::in | std::ios::binary);
|
||||||
|
if (in) {
|
||||||
|
getall(in, *out);
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::string to_upper(std::string src)
|
||||||
|
{
|
||||||
|
std::transform(src.begin(), src.end(), src.begin(), toupper);
|
||||||
|
return src;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline std::string to_lower(std::string src)
|
||||||
|
{
|
||||||
|
std::transform(src.begin(), src.end(), src.begin(), tolower);
|
||||||
|
return src;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::string to_hex(unsigned char c, bool lower = false)
|
||||||
|
{
|
||||||
|
const std::string hex = "0123456789ABCDEF";
|
||||||
|
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << hex[c >> 4] << hex[c & 0xf];
|
||||||
|
|
||||||
|
return lower ? to_lower(ss.str()) : ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline time_t now()
|
||||||
|
{
|
||||||
|
return time(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string utc_time(time_t timestamp)
|
||||||
|
{
|
||||||
|
struct tm result_tm;
|
||||||
|
char buffer[32];
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
gmtime_s(&result_tm, ×tamp);
|
||||||
|
#else
|
||||||
|
gmtime_r(×tamp, &result_tm);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
size_t size = strftime(buffer, 32, "%Y-%m-%dT%H:%M:%SZ", &result_tm);
|
||||||
|
|
||||||
|
return std::string(buffer, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void url_parse(
|
||||||
|
const std::string & url,
|
||||||
|
std::map<std::string, std::string> & params)
|
||||||
|
{
|
||||||
|
int pos = (int)url.find("?");
|
||||||
|
if (pos != -1)
|
||||||
|
{
|
||||||
|
int key_start = pos + 1,
|
||||||
|
key_len = 0,
|
||||||
|
val_start = 0;
|
||||||
|
for (int i = key_start; i <= (int)url.size(); ++i)
|
||||||
|
{
|
||||||
|
switch (url[i])
|
||||||
|
{
|
||||||
|
case '=':
|
||||||
|
key_len = i - key_start;
|
||||||
|
val_start = i + 1;
|
||||||
|
break;
|
||||||
|
case '\0':
|
||||||
|
case '&':
|
||||||
|
if (key_len != 0)
|
||||||
|
{
|
||||||
|
params[url.substr(key_start, key_len)] = url.substr(val_start, i - val_start);
|
||||||
|
key_start = i + 1;
|
||||||
|
key_len = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string url_encode(const std::string & input, bool encode_slash=true)
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
const char *str = input.c_str();
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < input.size(); i++)
|
||||||
|
{
|
||||||
|
unsigned char c = str[i];
|
||||||
|
if (isalnum(c) || c == '_' || c == '-' || c == '~' || c == '.' || (!encode_slash && c == '/'))
|
||||||
|
{
|
||||||
|
ss << c;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ss << "%" << to_hex(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string canonicalize_params(std::map<std::string, std::string> & params)
|
||||||
|
{
|
||||||
|
std::vector<std::string> v;
|
||||||
|
v.reserve(params.size());
|
||||||
|
|
||||||
|
for (auto & it : params) {
|
||||||
|
v.push_back(url_encode(it.first) + "=" + url_encode(it.second));
|
||||||
|
}
|
||||||
|
std::sort(v.begin(), v.end());
|
||||||
|
|
||||||
|
std::string result;
|
||||||
|
for (auto & it : v)
|
||||||
|
{
|
||||||
|
result.append((result.empty() ? "" : "&") + it);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string canonicalize_headers(std::map<std::string, std::string> & headers)
|
||||||
|
{
|
||||||
|
std::vector<std::string> v;
|
||||||
|
v.reserve(headers.size());
|
||||||
|
|
||||||
|
for (auto & it : headers) {
|
||||||
|
v.push_back(url_encode(to_lower(it.first)) + ":" + url_encode(it.second));
|
||||||
|
}
|
||||||
|
std::sort(v.begin(), v.end());
|
||||||
|
|
||||||
|
std::string result;
|
||||||
|
for (auto & it : v)
|
||||||
|
{
|
||||||
|
result.append((result.empty() ? "" : "\n") + it);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string get_headers_keys(std::map<std::string, std::string> & headers)
|
||||||
|
{
|
||||||
|
std::vector<std::string> v;
|
||||||
|
v.reserve(headers.size());
|
||||||
|
|
||||||
|
for (auto & it : headers) {
|
||||||
|
v.push_back(to_lower(it.first));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string result;
|
||||||
|
for (auto & it : v)
|
||||||
|
{
|
||||||
|
result.append((result.empty() ? "" : ";") + it);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string get_host(const std::string & url)
|
||||||
|
{
|
||||||
|
int pos = (int)url.find("://") + 3;
|
||||||
|
return url.substr(
|
||||||
|
pos,
|
||||||
|
url.find('/', pos) - pos
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::string get_path(const std::string & url)
|
||||||
|
{
|
||||||
|
int path_start = (int)url.find('/', url.find("://") + 3);
|
||||||
|
int path_end = (int)url.find('?');
|
||||||
|
path_end = path_end == -1 ? (int)url.size() : path_end;
|
||||||
|
|
||||||
|
return url.substr(path_start, path_end - path_start);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string hmac_sha256(
|
||||||
|
const std::string & src,
|
||||||
|
const std::string & sk)
|
||||||
|
{
|
||||||
|
const EVP_MD *evp_md = EVP_sha256();
|
||||||
|
unsigned char md[EVP_MAX_MD_SIZE];
|
||||||
|
unsigned int md_len = 0;
|
||||||
|
|
||||||
|
if (HMAC(evp_md,
|
||||||
|
reinterpret_cast<const unsigned char *>(sk.data()), (int)sk.size(),
|
||||||
|
reinterpret_cast<const unsigned char *>(src.data()), src.size(),
|
||||||
|
md, &md_len) == NULL)
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::stringstream ss;
|
||||||
|
for (int i = 0; i < (int)md_len; ++i)
|
||||||
|
{
|
||||||
|
ss << to_hex(md[i], true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
void sign(
|
||||||
|
std::string method,
|
||||||
|
std::string & url,
|
||||||
|
std::map<std::string, std::string> & params,
|
||||||
|
std::map<std::string, std::string> & headers,
|
||||||
|
std::string & ak,
|
||||||
|
std::string & sk)
|
||||||
|
{
|
||||||
|
url_parse(url, params);
|
||||||
|
headers["Host"] = get_host(url);
|
||||||
|
std::string timestamp = utc_time(now());
|
||||||
|
headers["x-bce-date"] = timestamp;
|
||||||
|
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << "bce-auth-v" << __BCE_VERSION__ << "/" << ak << "/"
|
||||||
|
<< timestamp << "/" << __BCE_EXPIRE__;
|
||||||
|
|
||||||
|
std::string val = ss.str();
|
||||||
|
std::string sign_key = hmac_sha256(val, sk);
|
||||||
|
|
||||||
|
ss.str("");
|
||||||
|
ss << to_upper(method) << '\n' << url_encode(get_path(url), false)
|
||||||
|
<< '\n' << canonicalize_params(params)
|
||||||
|
<< '\n' << canonicalize_headers(headers);
|
||||||
|
|
||||||
|
std::string signature = hmac_sha256(ss.str(), sign_key);
|
||||||
|
|
||||||
|
ss.str("");
|
||||||
|
ss << "bce-auth-v" << __BCE_VERSION__ << "/" << ak << "/"
|
||||||
|
<< timestamp << "/" << __BCE_EXPIRE__ << "/"
|
||||||
|
<< get_headers_keys(headers) << "/" << signature;
|
||||||
|
|
||||||
|
headers["authorization"] = ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include "ocr.h" // 用于调用接口
|
||||||
|
#include <string> // 用于 string 的操作
|
||||||
|
#include <codecvt> // 用于转码
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
const static string request_url = "https://aip.baidubce.com/rest/2.0/ocr/v1/license_plate";
|
||||||
|
static string result;
|
||||||
|
|
||||||
|
int lincesePlate(string &token, const char *image_path);
|
||||||
|
int callback(char *, size_t, size_t, void *);
|
||||||
|
|
||||||
|
int main(int argc, char const *argv[]) // argc: 参数个数, argv: 参数列表
|
||||||
|
{
|
||||||
|
|
||||||
|
if (argc < 2)
|
||||||
|
{
|
||||||
|
cout << "用法: " << argv[0] << " 车牌图片路径" << endl;
|
||||||
|
return 1; // 返回 1 表示失败
|
||||||
|
}
|
||||||
|
|
||||||
|
string token = "24.1509bd6033f9988f4e0f289b625dc0c8.2592000.1690601100.282335-35458273";
|
||||||
|
lincesePlate(token, argv[1]);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lincesePlate(string &token, const char *image_path)
|
||||||
|
{
|
||||||
|
// HTTP 请求的完整 URL 路径
|
||||||
|
string url = request_url + "?access_token=" + token;
|
||||||
|
CURL *curl; // 定义一个指向CURL类型的指针
|
||||||
|
CURLcode code; // 定义一个CURLcode类型的变量, 用于接收返回状态码
|
||||||
|
curl = curl_easy_init(); // 初始化一个CURL类型的指针
|
||||||
|
|
||||||
|
if (curl)
|
||||||
|
{
|
||||||
|
// 设置请求的 URL 地址
|
||||||
|
curl_easy_setopt(curl, CURLOPT_URL, url.data()); // url.data() 等于 url.c_str(), 返回一个指向正规 C 字符串的指针常量, 即返回一个指向以空字符终止的字符数组的指针
|
||||||
|
curl_easy_setopt(curl, CURLOPT_POST, 1); // 设置为非 0, 表示本次操作为 POST
|
||||||
|
|
||||||
|
string image;
|
||||||
|
aip::get_file_content(image_path, &image); // 读取图片文件
|
||||||
|
string img_base64 = aip::base64_encode(image.c_str(), image.length()); // 将图片文件转为 base64 编码, image.c_str(): 返回指向正规 C 字符串的指针常量, 即返回一个指向以空字符终止的字符数组的指针, image.length(): 返回字符串的长度
|
||||||
|
|
||||||
|
curl_httppost *post, *last; // *post: 指向第一个元素的指针, *last: 指向最后一个元素的指针
|
||||||
|
// 以表单的方式上传 image 字段的数据
|
||||||
|
curl_formadd(&post, &last, CURLFORM_COPYNAME, "image", CURLFORM_COPYCONTENTS, img_base64.data(), CURLFORM_END); // 参数说明: &post: 指向第一个元素的指针, &last: 指向最后一个元素的指针, CURLFORM_COPYNAME: 指定表单的字段名, CURLFORM_COPYCONTENTS: 指定表单字段的值, CURLFORM_END: 用于结束整个表单
|
||||||
|
curl_easy_setopt(curl, CURLOPT_HTTPPOST, post); // 设置表单字段和值
|
||||||
|
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, callback); // 设置回调函数
|
||||||
|
|
||||||
|
code = curl_easy_perform(curl); // 执行请求, 该函数完成后, 错误码将会写入 code 变量
|
||||||
|
cout << code << endl; // 打印结果
|
||||||
|
curl_easy_cleanup(curl); // 清除 curl 操作, 即结束本次请求
|
||||||
|
|
||||||
|
return 0; // 返回 0 表示成功
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr, "curl init failed!\n"); // 如果返回非 0, 则表示失败
|
||||||
|
return 1; // 返回 1 表示失败
|
||||||
|
}
|
||||||
|
|
||||||
|
int callback(char *buffer, size_t size, size_t nitems, void *outstream)
|
||||||
|
{
|
||||||
|
result = string(buffer, size * nitems); // 将 buffer 中的数据拷贝到 result 中
|
||||||
|
|
||||||
|
// 将 result 数据转化为 json 格式
|
||||||
|
Json::Reader json_type_result; // 定义一个 json 格式的变量
|
||||||
|
string error; // 定义一个 string 类型的变量, 用于接收错误信息
|
||||||
|
Json::CharReaderBuilder crbuilder; // CharReaderBuilder 类提供了一个简单的 API 来从字符流读取 JSON 文档
|
||||||
|
unique_ptr<Json::CharReader> reader(crbuilder.newCharReader()); // unique_ptr: 一个独占的指针, 用于管理另一个对象的生命周期, 该对象使用 delete 销毁
|
||||||
|
reader->parse(result.c_str(), result.c_str() + result.length(), &json_type_result, &error); // 将 result 转化为 json 格式
|
||||||
|
|
||||||
|
cout << result << endl; // 打印结果
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include "ocr.h" // 用于调用接口
|
||||||
|
#include <string> // 用于 string 的操作
|
||||||
|
#include <codecvt> // 用于转码
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
const static string request_url = "https://aip.baidubce.com/rest/2.0/ocr/v1/license_plate";
|
||||||
|
static string result;
|
||||||
|
|
||||||
|
int lincesePlate(string &token, const char *image_path);
|
||||||
|
int callback(char *, size_t, size_t, void *);
|
||||||
|
|
||||||
|
int main(int argc, char const *argv[]) // argc: 参数个数, argv: 参数列表
|
||||||
|
{
|
||||||
|
|
||||||
|
if (argc < 2)
|
||||||
|
{
|
||||||
|
cout << "用法: " << argv[0] << " 车牌图片路径" << endl;
|
||||||
|
return 1; // 返回 1 表示失败
|
||||||
|
}
|
||||||
|
|
||||||
|
string token = "24.1509bd6033f9988f4e0f289b625dc0c8.2592000.1690601100.282335-35458273";
|
||||||
|
lincesePlate(token, argv[1]);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lincesePlate(string &token, const char *image_path)
|
||||||
|
{
|
||||||
|
// HTTP 请求的完整 URL 路径
|
||||||
|
string url = request_url + "?access_token=" + token;
|
||||||
|
CURL *curl; // 定义一个指向CURL类型的指针
|
||||||
|
CURLcode code; // 定义一个CURLcode类型的变量, 用于接收返回状态码
|
||||||
|
curl = curl_easy_init(); // 初始化一个CURL类型的指针
|
||||||
|
|
||||||
|
if (curl)
|
||||||
|
{
|
||||||
|
// 设置请求的 URL 地址
|
||||||
|
curl_easy_setopt(curl, CURLOPT_URL, url.data()); // url.data() 等于 url.c_str(), 返回一个指向正规 C 字符串的指针常量, 即返回一个指向以空字符终止的字符数组的指针
|
||||||
|
curl_easy_setopt(curl, CURLOPT_POST, 1); // 设置为非 0, 表示本次操作为 POST
|
||||||
|
|
||||||
|
string image;
|
||||||
|
aip::get_file_content(image_path, &image); // 读取图片文件
|
||||||
|
string img_base64 = aip::base64_encode(image.c_str(), image.length()); // 将图片文件转为 base64 编码, image.c_str(): 返回指向正规 C 字符串的指针常量, 即返回一个指向以空字符终止的字符数组的指针, image.length(): 返回字符串的长度
|
||||||
|
|
||||||
|
curl_httppost *post, *last; // *post: 指向第一个元素的指针, *last: 指向最后一个元素的指针
|
||||||
|
// 以表单的方式上传 image 字段的数据
|
||||||
|
curl_formadd(&post, &last, CURLFORM_COPYNAME, "image", CURLFORM_COPYCONTENTS, img_base64.data(), CURLFORM_END); // 参数说明: &post: 指向第一个元素的指针, &last: 指向最后一个元素的指针, CURLFORM_COPYNAME: 指定表单的字段名, CURLFORM_COPYCONTENTS: 指定表单字段的值, CURLFORM_END: 用于结束整个表单
|
||||||
|
curl_easy_setopt(curl, CURLOPT_HTTPPOST, post); // 设置表单字段和值
|
||||||
|
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, callback); // 设置回调函数
|
||||||
|
|
||||||
|
code = curl_easy_perform(curl); // 执行请求, 该函数完成后, 错误码将会写入 code 变量
|
||||||
|
cout << code << endl; // 打印结果
|
||||||
|
curl_easy_cleanup(curl); // 清除 curl 操作, 即结束本次请求
|
||||||
|
|
||||||
|
return 0; // 返回 0 表示成功
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr, "curl init failed!\n"); // 如果返回非 0, 则表示失败
|
||||||
|
return 1; // 返回 1 表示失败
|
||||||
|
}
|
||||||
|
|
||||||
|
int callback(char *buffer, size_t size, size_t nitems, void *outstream)
|
||||||
|
{
|
||||||
|
result = string(buffer, size * nitems); // 将 buffer 中的数据拷贝到 result 中
|
||||||
|
cout << result << endl; // 打印结果
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
// 编写一个函数,用于判断一个整数是否为质数,并返回结果。
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
bool isPrime(int n)
|
||||||
|
{
|
||||||
|
if (n <= 1)
|
||||||
|
return false;
|
||||||
|
int i = 2;
|
||||||
|
while (i * i <= n)
|
||||||
|
{
|
||||||
|
if (n % i == 0)
|
||||||
|
return false; // 不是质数
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return true; // 是质数
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
cout << "请输入一个整数:";
|
||||||
|
cin >> n;
|
||||||
|
if (isPrime(n))
|
||||||
|
cout << n << " 是质数" << endl;
|
||||||
|
else
|
||||||
|
cout << n << " 不是质数" << endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
// 编写一个函数,用于计算两个整数的和,并返回结果。
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
int sum(int a, int b)
|
||||||
|
{
|
||||||
|
return a + b;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
int a, b;
|
||||||
|
cout << "请输入两个整数:";
|
||||||
|
cin >> a >> b;
|
||||||
|
cout << "两个整数的和为:" << sum(a, b) << endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
// 编写一个函数,用于计算一个整数的二进制表示中1的个数及0的个数,并返回结果。
|
||||||
|
#include <iostream>
|
||||||
|
#include <bitset>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
// 1 的个数
|
||||||
|
int countOne(int n)
|
||||||
|
{
|
||||||
|
|
||||||
|
int cnt = 0;
|
||||||
|
int temp = 0;
|
||||||
|
for (int i = 0; temp < n; i++)
|
||||||
|
{
|
||||||
|
temp = 1 << i;
|
||||||
|
if ((n & temp) == temp)
|
||||||
|
cnt++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 0 的个数
|
||||||
|
int countZero(int n)
|
||||||
|
{
|
||||||
|
int cnt = 0;
|
||||||
|
int temp = 0;
|
||||||
|
for (int i = 0; temp < n; i++)
|
||||||
|
{
|
||||||
|
temp = 1 << i;
|
||||||
|
if ((n | ~temp) == ~temp)
|
||||||
|
cnt++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (temp > n)
|
||||||
|
return cnt - 1;
|
||||||
|
return cnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 逆向打印函数
|
||||||
|
void print(int n)
|
||||||
|
{
|
||||||
|
int temp = 0;
|
||||||
|
for (int i = 0; temp < n; i++)
|
||||||
|
{
|
||||||
|
temp = 1 << i;
|
||||||
|
if ((n & temp) == temp)
|
||||||
|
cout << "1"
|
||||||
|
<< " ";
|
||||||
|
if ((n | ~temp) == ~temp)
|
||||||
|
cout << "0"
|
||||||
|
<< " ";
|
||||||
|
}
|
||||||
|
cout << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
cout << "请输入一个整数: ";
|
||||||
|
cin >> x;
|
||||||
|
cout << x << " 的二进制表示为: " << bitset<12>(x) << endl;
|
||||||
|
cout << x << " 的我的二进制表示为: " << endl;
|
||||||
|
print(x);
|
||||||
|
cout << x << " 的二进制表示中 1 的个数为: " << countOne(x) << endl;
|
||||||
|
cout << x << " 的二进制表示中 0 的个数为: " << countZero(x) << endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
// 编写一个函数,用于计算一个整数数组中所有元素的和,并返回结果。
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
// int mySize(int arr[])
|
||||||
|
// {
|
||||||
|
// int size = 0;
|
||||||
|
// while (arr[size] && ++size)
|
||||||
|
// ;
|
||||||
|
// return size;
|
||||||
|
// }
|
||||||
|
|
||||||
|
int sum(int arr[], int size)
|
||||||
|
{
|
||||||
|
int sum = 0;
|
||||||
|
while (--size >= 0)
|
||||||
|
{
|
||||||
|
sum += arr[size];
|
||||||
|
}
|
||||||
|
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
int arr[] = {1, 2, 3, 4, 5, 6};
|
||||||
|
// int size = mySize(arr);
|
||||||
|
int size = sizeof(arr) / sizeof(arr[0]);
|
||||||
|
cout << "数组的长度为:" << size << endl;
|
||||||
|
cout << "数组的和为:" << sum(arr, size) << endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
// 编写一个函数,用于计算一个整数数组中所有元素的平均值,并返回结果。
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
double average(int arr[], int size)
|
||||||
|
{
|
||||||
|
int sum = 0;
|
||||||
|
int size_copy = size;
|
||||||
|
while (--size >= 0)
|
||||||
|
{
|
||||||
|
sum += arr[size];
|
||||||
|
}
|
||||||
|
|
||||||
|
return sum / (double)size_copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
int arr[] = {1, 2, 3, 4, 5, 6};
|
||||||
|
int size = sizeof(arr) / sizeof(arr[0]);
|
||||||
|
cout << "数组的平均值为:" << average(arr, size) << endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
// 编写一个函数,用于将一个整数数组按照从小到大的顺序进行排序。
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
void sort(int arr[], int size)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
// 等同于 for (int j = 0; j < size - i - 1; j++) 但是效率更高
|
||||||
|
// 为什么效率更高?因为每次循环都会将最大的数放到最后,所以每次循环都可以少比较一次
|
||||||
|
for (int j = i + 1; j < size; j++)
|
||||||
|
{
|
||||||
|
if (arr[i] > arr[j])
|
||||||
|
{
|
||||||
|
arr[i] = arr[i] ^ arr[j];
|
||||||
|
arr[j] = arr[i] ^ arr[j];
|
||||||
|
arr[i] = arr[i] ^ arr[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
int arr[] = {1, 3, 2, 5, 4, 6};
|
||||||
|
int size = sizeof(arr) / sizeof(arr[0]);
|
||||||
|
sort(arr, size);
|
||||||
|
cout << "排序后的数组为:";
|
||||||
|
for (int i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
cout << arr[i] << " ";
|
||||||
|
}
|
||||||
|
cout << endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
// 编写一个函数,用于将一个字符串中的所有小写字母转换为大写字母,并返回结果。
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
void toUpper(char str[], int size)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
// if (str[i] >= 'a' && str[i] <= 'z')
|
||||||
|
// str[i] -= 32;
|
||||||
|
|
||||||
|
// 位运算实现
|
||||||
|
if (str[i] >= 'a' && str[i] <= 'z')
|
||||||
|
str[i] &= ~32; // 原理, 32 = 0010 0000, ~32 = 1101 1111, 与运算后, 小写字母的第6位变为0, 即变为大写字母
|
||||||
|
|
||||||
|
// 三目运算符
|
||||||
|
// str[i] = (str[i] > 'a' && str[i] < 'z') ? str[i] - 32 : str[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
char str[] = "abcdeFG";
|
||||||
|
int size = sizeof(str) / sizeof(str[0]);
|
||||||
|
toUpper(str, size);
|
||||||
|
cout << "转换后的字符串为:" << str << endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
// 编写一个函数,用于计算一个整数的阶乘,并返回结果。
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
int factorial(int n)
|
||||||
|
{
|
||||||
|
int result = 1;
|
||||||
|
while (n)
|
||||||
|
{
|
||||||
|
result *= n;
|
||||||
|
n--;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
cout << "请输入一个整数:";
|
||||||
|
cin >> n;
|
||||||
|
cout << n << "! = " << factorial(n) << endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
// 编写一个函数,用于计算一个整数的平方根,并返回结果。
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
int squareRoot(int x)
|
||||||
|
{
|
||||||
|
int left = 0, right = x;
|
||||||
|
int mid;
|
||||||
|
while (left <= right)
|
||||||
|
{
|
||||||
|
mid = (left + right) / 2;
|
||||||
|
if (mid * mid == x)
|
||||||
|
return mid;
|
||||||
|
else if (mid * mid < x)
|
||||||
|
left = mid + 1;
|
||||||
|
else
|
||||||
|
right = mid - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1; // 找不到平方根
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
cout << "请输入一个整数: ";
|
||||||
|
cin >> x;
|
||||||
|
|
||||||
|
int result = squareRoot(x);
|
||||||
|
if (result == -1)
|
||||||
|
cout << x << " 找不到平方根" << endl;
|
||||||
|
else
|
||||||
|
cout << x << " 的平方根为: " << result << endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
// 编写一个函数,用于判断一个字符串是否为回文字符串,并返回结果。
|
||||||
|
#include <iostream>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
bool isPalindrome(const char *str) // const 有只读的含义, 不会修改 str 指向的字符串
|
||||||
|
{
|
||||||
|
int len = strlen(str);
|
||||||
|
int i = 0, j = len - 1;
|
||||||
|
while (i < j)
|
||||||
|
{
|
||||||
|
if (str[i] != str[j])
|
||||||
|
return false;
|
||||||
|
i++;
|
||||||
|
j--;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
char str[100];
|
||||||
|
cout << "请输入一个字符串:";
|
||||||
|
cin >> str;
|
||||||
|
|
||||||
|
if (isPalindrome(str))
|
||||||
|
cout << str << " 是回文字符串" << endl;
|
||||||
|
else
|
||||||
|
cout << str << " 不是回文字符串" << endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||