QT 新手小白USBCAN 学习

2023-10-27

一、 介绍CAN总线

 CAN总线介绍

二、USBCAN总线

  2.1 产品介绍

        USBCAN 转换器模块实现了将 CAN 总线接口与 USB 接口进行相互转换。可以 简单方便的通过电脑监视 CAN 总线网络,同时可以实现工业现场数据稳定的双 向通信。模块广泛应用与工业控制、汽车电子、安防监控等领域的通信、控制、 数据传输。

       本模块是在电脑上将 USB 接口虚拟成串口设备实现通信,用户在电脑上只需 要掌握串口通信相关知识即可使用,具有使用方便、二次开发简单、稳定可靠等特点。

  2.2 接口说明

(1)MODE:将该跳线连接上,将强制产品进入设置模式

(2)RES:终端匹配电阻。将跳线连接上,则 CAN 总线接入 120 欧姆终端匹配电阻,跳线断开则没有终端匹配电阻接入。

(3) CAN_H 和 CAN_L:CAN 总线信号,和其他设备连接时 CAN_H 连 CAN_H 信号,CAN_L 连 CAN_L 信号,注意不能接反。 

(4)GND:模块内部地信号,非必须信号,如果线缆有屏蔽层,用户可自由选 择是否将该信号连接与屏蔽增连接。 

  2.3 包模式

         包模式下,串口处为固定 16byte 包长,数据不足部分补 0。这种模式下用户可以随意控制 CAN 总线上发出报文。串口处包格式说明:

 三、QT调用第三方库环境搭建

首先在QT工程中新建一个项目,并编译运行程序(在项目中把Shadow build去掉)把库函数文件都放在工作目录下。库函数文件总共有三个文件:ControlCAN.h、 ControlCAN.lib、ControlCAN.dll 和一个文件夹 kerneldlls。在.pro文件中加入

LIBS += -L$$PWD/./ ControlCAN.lib ControlCAN.dll

INCLUDEPATH += $$PWD\ControlCAN.h

 并在构造函数中添加 #include "ControlCAN.h"  #include<QDebug>头文件和测试

 1.选择32位

            2.去掉Shadow build

      3. 编译运行

 4. 将库放入把库函数文件都放在工作目录下

      5 .pro中添加环境变量 

                6 添加测试代码编译运行通过

                           7. 运行成功 (用的双头usbcan口同时插入电脑后编译通过)

四、USBCAN第三方库函数介绍

使用流程图

  整体流程分六个步骤:

1.打开设备  VCI_OpenDevice()

VCI_OpenDevice(DWORD DevType, DWORD DevIndex, DWORD Reserved);

2.初始化某一路  VCI_InitCAN()

VCI_InitCAN(DWORD DevType, DWORD DevIndex, DWORD CANIndex, PVCI_INIT_CONFIG pInitConfig);

3.启动某一路  VCI_StartCAN()

VCI_StartCAN(DWORD DevType, DWORD DevIndex, DWORD CANIndex);

4.读取CAN帧  VCI_Receive()

VCI_Receive(DWORD DevType, DWORD DevIndex, DWORD CANIndex, PVCI_CAN_OBJ pReceive, ULONG Len, INT WaitTime=-1);

5.发送CAN帧  VCI_Transmit()

VCI_Transmit(DWORD DevType, DWORD DevIndex, DWORD CANIndex, PVCI_CAN_OBJ pSend, ULONG Len);

6.关闭设备  VCI_CloseDevice()

 VCI_CloseDevice(DWORD DevType, DWORD DevIndex);

通用类型:

DevType

设备类型号。对应不同的产品型号。

DevIndex

设备索引号。比如当只有一个 PCIe-9221 时,索引号为 0,这时再插入一个 PCIe-9221

那么后面插入的这个设备索引号就是 1,以此类推。

CANIndex

第几路 CAN。即对应卡的 CAN 通道号,CAN0 0CAN1 1,以此类推。

详细看CAN API使用说明

5  QT下CAN总线代码编写思路

(代码质量很一般仅学习。)

mainwindow.h


#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include "ControlCAN.h"
#include <QThread>
#include "recever.h"
#include"send_thread.h"
#include<QMutex>

#define DevType   4  // PCIe-9221
#define DevIndex  0 // 索引号0
#define CANIndex  0   //CAN0通道



QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow

{
    Q_OBJECT

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


    bool Start();

    void Stop();

    bool InitSerial();

    void setUI();

    void Close();

    void ResetCAN();

 signals:

   void receve();

   void Write(const QString &data,BYTE ,BYTE ,BYTE );

private slots:

    void on_btn_openConsole_clicked();

    void on_btn_openConsole_2_clicked();

    void on_btn_openConsole_3_clicked();

    void on_btn_recev_clicked();

    void Readdata(const QString &);

    void on_btn_send_clicked();

    void on_pushButton_3_clicked();

private:

    Ui::MainWindow *ui;

    bool IsRunning_ = false;


    recever *mrecever;

    send_thread *Send_thread;

    QThread mThread;

    QThread sendThread;

    DWORD REL;

    VCI_INIT_CONFIG Init;

    QMutex mutex;


};

#endif // MAINWINDOW_H

 recever.h

#ifndef RECEVER_H
#define RECEVER_H
#include <QObject>
#include "ControlCAN.h"
#define DevType   4  // PCIe-9221
#define DevIndex  0 // 索引号0
#define CANIndex  0   //CAN0通道

class recever: public QObject
{
    Q_OBJECT

public:
    explicit recever(QObject *parent = nullptr);

     void VCI_Rece();

    DWORD dwRel=false;

    bool CloseREL=false;

public slots:
   void readData();

signals:
    void SignalRead(const QString &);

private:
   DWORD ReceiveNum;
    VCI_CAN_OBJ Receive[100];

};

#endif // RECEVER_H

send_thread.h


#ifndef SEND_THREAD_H
#define SEND_THREAD_H
#include <QObject>
#include "ControlCAN.h"
#define DevType   4  // PCIe-9221
#define DevIndex  0 // 索引号0
#define CANIndex  0   //CAN0通道

class send_thread : public QObject
{
    Q_OBJECT
public:
    explicit send_thread(QObject *parent = nullptr);

     QByteArray  HexStringToByteArray(QString hex, bool *ok);
signals:

public slots:
      void SlotDoWrite(const QString &data,BYTE ,BYTE ,BYTE);

private:
    VCI_CAN_OBJ vco;
};

#endif // SEND_THREAD_H

mainwindow.c

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

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

    setUI();
    mrecever = new recever;
    Send_thread = new send_thread;
    mrecever->moveToThread(&mThread);
    Send_thread->moveToThread(&sendThread);

    qRegisterMetaType<DWORD>("DWORD");

    qDebug()<< "main::SlotSessionDisConnected " << QThread::currentThreadId();
    connect(this,&MainWindow::receve,mrecever,&recever::readData);
    connect(mrecever,&recever::SignalRead,this,&MainWindow::Readdata,Qt::DirectConnection);
    connect(this,&MainWindow::Write,Send_thread,&send_thread::SlotDoWrite);

}

MainWindow::~MainWindow()
{
   // disconnect(this,&Widget::receve,mComservice,&ComService::readData);
    //disconnect(mComservice,&ComService::SignalRead,this,&Widget::Readdata);
    this->Close();
    mThread.quit();
    mThread.wait();
    sendThread.quit();
    sendThread.wait();
     delete mrecever;
    delete Send_thread;
    delete ui;
}


void MainWindow::setUI()
{
    setFixedHeight(446);
    setFixedWidth(544);
    ui->btn_recev->setEnabled(false);
    ui->btn_send->setEnabled(false);
    ui->btn_openConsole_2->setEnabled(false);
    ui->btn_openConsole_3->setEnabled(false);

    ui->comboBox->addItem("正常发送");
    ui->comboBox->addItem("单次发送");
    ui->comboBox->addItem("自发自收");
    ui->comboBox->addItem("单次自发自收");

    ui->comboBox_2->addItem("标准帧");
    ui->comboBox_2->addItem("扩展帧");

    ui->comboBox_3->addItem("数据帧");
    ui->comboBox_3->addItem("远程帧");

}

bool MainWindow::Start()
{
    if(IsRunning_)
        return true;
    mThread.start();
    sendThread.start();
    IsRunning_ = true;
    return true;

}

void MainWindow::Stop()
{
    if(!IsRunning_)
        return;
    mThread.quit();
    mThread.wait();
    sendThread.quit();
    sendThread.wait();
    IsRunning_=false;


}

bool MainWindow::InitSerial()
{
    mrecever->dwRel=false;
    mrecever->CloseREL=false;

    REL=VCI_OpenDevice(DevType,DevIndex,0);

    if(REL!= 1) return FALSE;  //打开设备

    Init.Timing0=0;
    Init.Timing1=0x1C;
    Init.Mode=0;
    Init.AccMask=0xFFFFFFFF;
    Init.Filter=1;

    if(VCI_InitCAN(DevType,DevIndex,CANIndex,&Init)!= 1) FALSE;      //初始化设备

    if(VCI_StartCAN(DevType,DevIndex,CANIndex)!=1)  FALSE ;          //运行设备

    return true;
}


void MainWindow::on_btn_openConsole_clicked()
{

    if(ui->btn_openConsole->text()==tr("打开CAN口"))
    {

        if(!Start())
            return;

        if(!InitSerial())
        {
            QMessageBox::information(this,"打开CAN口","CAN口打开失败");
            return;
        }
        QMessageBox::information(this,"打开CAN口","CAN口打开成功");

        if(!mrecever->dwRel||!mrecever->CloseREL)
        {
            mrecever->CloseREL=0;
            mrecever->dwRel=0;

            emit receve();

        }

        ui->btn_recev->setEnabled(false);
        ui->btn_send->setEnabled(true);
        ui->btn_openConsole_2->setEnabled(true);
        ui->btn_openConsole_3->setEnabled(true);
        ui->btn_openConsole->setEnabled(false);
    }


}


void MainWindow::on_btn_openConsole_2_clicked()
{
    // if(VCI_CloseDevice(DevType, DevIndex) != 1) qDebug()<<"error";

     Close();

    if(mrecever->CloseREL)
    {
        ui->btn_openConsole->setEnabled(true);
        ui->btn_openConsole_2->setEnabled(false);
        ui->btn_openConsole_3->setEnabled(false);
        ui->btn_send->setEnabled(false);
        ui->btn_recev->setEnabled(false);
        QMessageBox::information(this,"关闭CAN口","CAN口关闭成功");
        Stop();
    }

}


void MainWindow::Close()
{
    mutex.lock();
    qDebug()<< "SerialThreadsClose::SlotSessionDisConnected123 " << QThread::currentThreadId();
    if(!mrecever->CloseREL)
    {
    if(VCI_CloseDevice(DevType, DevIndex)==1)
    {
        qDebug()<<"CAN口关闭成功";
        mrecever->CloseREL=TRUE;
    }
    }

    mutex.unlock();
    // mutex.unlock();
}

void MainWindow::Readdata(const QString &temp)
{
    ui->textEdit_recv->append(temp.toLocal8Bit());
}

void MainWindow::on_btn_openConsole_3_clicked()
{
    ResetCAN();

    if(mrecever->dwRel)
    {
        ui->btn_recev->setEnabled(true);
    }
    qDebug()<<mrecever->dwRel;
}

void MainWindow::ResetCAN()
{
    mutex.lock();

    mrecever->dwRel= VCI_ResetCAN(DevType, DevIndex, CANIndex);

    if(mrecever->dwRel!=1) qDebug()<<"error";

    if(VCI_StartCAN(DevType, DevIndex, CANIndex)!=1) qDebug()<<"error";

    else  qDebug()<<"复位成功";

    mutex.unlock();
}


//接收
void MainWindow::on_btn_recev_clicked()
{

    qDebug()<<mrecever->dwRel<<mrecever->CloseREL;
    if(!mrecever->dwRel||!mrecever->CloseREL)
    {
        mrecever->CloseREL=0;
        mrecever->dwRel=0;
        emit receve();
        ui->btn_recev->setEnabled(false);
    }
    else qDebug()<<"接收中ing";
}

//发送





void MainWindow::on_btn_send_clicked()
{

        qRegisterMetaType<BYTE>("BYTE") ;
        BYTE SendType=0; BYTE RemoteFlag=0;  BYTE ExternFlag=0;

        if(ui->comboBox->currentText()=="正常发送")    SendType=0;
            if(ui->comboBox->currentText()=="单次发送")    SendType=1;
            if(ui->comboBox->currentText()=="自发自收")    SendType=2;
            if(ui->comboBox->currentText()=="单次自发自收") SendType=3;

            if(ui->comboBox_2->currentText()=="标准帧")    RemoteFlag=0;
            if(ui->comboBox_2->currentText()=="扩展帧")    RemoteFlag=1;

            if(ui->comboBox_3->currentText()=="数据帧")    ExternFlag=0;
            if(ui->comboBox_3->currentText()=="远程帧")    ExternFlag=1;

            qDebug()<<"扩展帧"<<SendType<<RemoteFlag<<ExternFlag;
            QString sendMsg = ui->textEdit_send->toPlainText();


            if(sendMsg.isEmpty())

            sendMsg="00 00 00 00 00 00 00 00";

            qDebug()<<"sendMsg"<<sendMsg;

             emit Write(sendMsg,SendType,RemoteFlag,ExternFlag);


}


void MainWindow::on_pushButton_3_clicked()
{
     ui->textEdit_recv->clear();
}

 recever.c


#include "recever.h"
#include <QDebug>
#include<QThread>
recever::recever(QObject *parent)
    : QObject{parent}
{

}


void recever::readData()
{
    BYTE num;
    qDebug() << "receve::SlotDoWrite threadID:"<< QThread::currentThreadId();

    while(1)
    {
        QThread::msleep(500);

        //qDebug()<<num;
        num=VCI_GetReceiveNum(DevType,DevIndex,CANIndex);
        qDebug()<<num;


        if(num)
        {
            VCI_Rece();
        }
        qDebug()<<dwRel<<dwRel;
        if(dwRel||CloseREL)
        {

            return;
        }

    }


}

void recever::VCI_Rece()
{
    qDebug()<< "VCI_Rece::SlotSessionDisConnected123 " << QThread::currentThreadId();

    QByteArray strData;
    strData.resize(8);

    ReceiveNum=  VCI_Receive(DevType,DevIndex,CANIndex,Receive,10,-1);
    qDebug()<<"ReceiveNum:"<<ReceiveNum;
    for (int i = 0; i < ReceiveNum; i++)
    {

        strData[0]  = Receive[i].Data[0];
        strData[1]  = Receive[i].Data[1];
        strData[2]  = Receive[i].Data[2];
        strData[3]  = Receive[i].Data[3];
        strData[4]  = Receive[i].Data[4];
        strData[5]  = Receive[i].Data[5];
        strData[6]  = Receive[i].Data[6];
        strData[7]  = Receive[i].Data[7];

        QString string_temp = (QString(strData.toHex(' ').toUpper().append(' ')));
        qDebug()<<ReceiveNum<<":data:"<<string_temp;
        emit SignalRead(string_temp);
        return;
    }
}

send_thread.c


#include "send_thread.h"
#include <QDataStream>
#include <QDebug>
#include<QThread>
#include<QtCore>

send_thread::send_thread(QObject *parent)
    : QObject{parent}
{

}

void send_thread::SlotDoWrite(const QString &data,BYTE SendType,BYTE RemoteFlag,BYTE ExternFlag)
{
    qDebug() << "write::SlotDoWrite threadID:"<< QThread::currentThreadId();

    vco.SendType = SendType; // 正常发送
    vco.RemoteFlag = RemoteFlag; // 数据帧
    vco.ExternFlag = ExternFlag; // 标准帧
    vco.DataLen = 8; // 数据长度1个字节


    bool ok;
    QByteArray buff=HexStringToByteArray(data, &ok);



   // QByteArray buff=HexStringToByteArray(data, &ok);
    qDebug()<<buff.toHex().toUpper();

    //QDataStream out(buff);


    vco.Data[0] = static_cast<unsigned char>(buff.at(0));
    vco.Data[1] = static_cast<unsigned char>(buff.at(1));
    vco.Data[2] = static_cast<unsigned char>(buff.at(2));
    vco.Data[3] = static_cast<unsigned char>(buff.at(3));
    vco.Data[4] = static_cast<unsigned char>(buff.at(4));
    vco.Data[5] = static_cast<unsigned char>(buff.at(5));
    vco.Data[6] = static_cast<unsigned char>(buff.at(6));
    vco.Data[7] = static_cast<unsigned char>(buff.at(7));

    if(VCI_Transmit(DevType,  DevIndex, CANIndex,&vco , 1)<0)   qDebug()<<"发送失败" ;

}


QByteArray send_thread:: HexStringToByteArray(QString hex, bool *ok)
{
    int p;

    QByteArray ret;
    QStringList lst = hex.simplified().split(' ');//转化为字符串数组
    ret.resize(lst.count());
    for(int i = 0; i < lst.count(); i++)
    {
        p = lst[i].toInt(ok, 16);
        if(!(*ok) || p > 255 )
        {
            return 0;
        }
        ret[i] = p;
    }
    return ret;
}

 最终效果图

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

QT 新手小白USBCAN 学习 的相关文章

  • QWidget::showMinimized() 不起作用

    在 Ubuntu 13 04 上 如果使用QWidget showMinimized 为了最小化窗口 我发现通过单击系统任务栏上的应用程序图标恢复它后 调用QWidget showMinimized 无法工作 connect minimum
  • 使用嵌入qt的mysql?

    我正在尝试使用嵌入 QT 的 mysql 我已经有一个与 mysqld 链接的 Qt mysql 插件 该插件可以很好地加载嵌入式数据库 但 QT 没有简单的方法来设置 dataDir 等嵌入式选项 我在这里看到 http doc qt i
  • 如何使用 ClangCodeModel 插件在 QtCreator 中设置 C++ 标准?

    抱歉 如果这是一个愚蠢的问题 但我已经尝试了几乎所有的方法 现在正在用头撞墙 问题是 带有 Clang 代码模型插件的 QtCreator 4 8 0 beta for Windows 解析我的项目 为 C 98 而实际上它是 C 17 但
  • 如何将枚举类传递给 QML?

    我正在学习QML with Qt并在通过时遇到一些麻烦enum class to qml 当我使用信号时int参数 一切正常 代码运行完美 But 麻烦就在这里 如果我使用信号与一些enum class我有参数undefinedqml 信号
  • QObject多重继承

    我正在尝试在 C Qt 类中使用 mix 来提供一大堆具有通用接口的小部件 该接口是以这样的方式定义的 如果它被定义为其他小部件类的基类 那么小部件本身将具有这些信号 class SignalInterface public QObject
  • 如何在不同的QT线程中创建一个窗口?

    我有一个应用程序 其中每个线程 主线程除外 都需要创建自己的窗口 我尝试创建一个线程然后调用this gt exec in the run功能 然而 在我接到那个电话之前我就收到了一个错误 ASSERT failure in QWidget
  • cmake 找不到 Qt4

    由于4 8 0已经发布 我重新安装了Qt 现在我也想使用cmake 为了使 cmake 工作 我记得必须添加 mingw bin 文件夹 QtSDK Desktop Qt 4 7 3 到Qt4 7 3中的PATH 所以我猜测在中会有一个类似
  • 如何使用 qt 库中的调试符号为 qt 5.5 创建开发 shell

    我有一个开发外壳buildInputs条目包括qt55 qtbase 这很好用 今天 我在 qt 库中发生了段错误 我想要带有调试符号的 qt 库 我看了一下nixpkgs pkgs development libraries qt 5 5
  • 运行最新版本时没有“最新”消息?

    我正在尝试使用Sparkle https sparkle project org与 Qt Go 的绑定 https github com therecipe qt app 闪光 m import
  • qvariant 作为 qhash 中的键

    我想创建一个带有 QVariants 键的数据结构 它看起来像这样 QHash
  • 如何通过信号和槽传递参数?

    我的 GUI 包括LineEdit and a 按钮 当 的时候按钮单击后 插槽clicked 叫做 我想在之间建立信号槽关系clicked 作为信号和doSomething 作为插槽 问题是doSomething 无权访问 UI 并且do
  • Qt - QProcess 不工作

    我尝试启动 Internet Explorer 所以我使用下面的代码 QProcess process new QProcess this QString temp C Program Files Internet Explorer iex
  • Qt - 意外的 GDB 退出

    我正在尝试开发一个应用程序 该应用程序创建图像并使用双线性插值填充颜色像素 然后显示它 到目前为止我的代码如下 include
  • Qt:关闭期间线程仍在运行时 qthread 被销毁

    我有一堂课 class centralDataPool public QObject Q OBJECT public centralDataPool QObject parent 0 centralDataPool commMonitor
  • Qmake 不支持源目录下的构建目录

    我创建了一个可以在 OS X 上编译和运行的应用程序 我现在想开始让它在 Windows 上运行 首先 我将项目复制到 Windows 机器上并尝试编译 但收到此错误 警告 Qmake不支持源目录下的构建目录 有任何想法吗 将影子构建目录设
  • 在 Windows 上静默安装 Qt55 Enterprise

    编辑 在 Qt 支持的帮助下 我已经解决了如何自动化 Qt 企业安装程序的这两个部分 下面是脚本调用 我正在尝试在 Windows 8 1 和 Windows 10 上静默安装 Qt 5 5 1 Enterprise 使用 script 开
  • PyQt:使用 alpha 通道创建 QPixmap,而不是预乘颜色通道

    我想创建一个 QPixmap 来使用 QPainter 进行绘制 QPixmap 应支持透明度 而不使用预乘颜色通道 目前 我通过创建具有所需尺寸的 QPixmap 并用每个通道 包括 alpha 设置为零的 QColor 填充它来实现此目
  • 使用样式表时的 QTabWidget tabPosition

    我目前正在使用样式表来设计应用程序的主题 这是我用于 QTabWidget 的样式表 QTabBar et QTabWidget QTabBar tab background qlineargradient spread pad x1 0
  • 如何从 ffmpeg 中打开的文件获取流信息?

    我正在尝试使用 ffmpeg 读取视频文件 我有与其旧版本相对应的工作代码 并开始尝试升级到最新的构建版本 将所有这些已弃用的函数替换为其实际的类似函数 但是我遇到了问题 似乎没有检索到任何流 并且视频负载停止在轨道中 这是我正在使用的代码
  • 在 Qt 中构建 Android 项目不再有效

    所以我对 Android SDK NDK 和 Apache Ant 进行了一些更新 现在我无法构建任何 Android 项目 我收到一条警告 然后它说找不到 build xml 文件 错误 Warning Android platform

随机推荐

  • MongoDB 系统管理与操作详解

    一 MongoDB 启动与关闭 1 启动MongoDB 执行mongod命令即可启动MongoDB服务器 mongod在启动时可使用许多可配置选项 在命令行中运行mongod help可列出这些选项 下列选项十分常用 需着重注意 dbpat
  • JVM——垃圾回收

    垃圾回收 文章目录 垃圾回收 垃圾回收概述 什么是垃圾 为什么要回收垃圾 内存溢出和内存泄漏 java垃圾回收机制 自动内存管理 应该关心哪些区域的回收 垃圾回收相关算法 垃圾标记阶段算法 如何标记一个垃圾对象 什么样的对象能被标记为垃圾对
  • IntelliJ IDEA 高级调试技巧

    一 条件断点 循环中经常用到这个技巧 比如 遍历1个大List的过程中 想让断点停在某个特定值 参考上图 在断点的位置 右击断点旁边的小红点 会出来一个界面 在Condition这里填入断点条件即可 这样调试时 就会自动停在i 10的位置
  • WinPcap实战(一)——发送ARP包

    ARP包的结构 ARP包格式 物理帧头 14B ARP帧结构 28B 填充数据 18B CRC 4B 这里给出一张图 图中没有18字节的填充数据和4字节的校验位 物理帧头 14B 目的MAC 6B 源MAC 6B 类型 2B ARP帧 0x
  • 小程序通过webview实现本地任意文件上传

    微信小程序做文件上传的时候 只能选择相册的图片或者视频 没办法选择手机内存卡里的文件 比如 word pdf文件等等 下面可以通过 webview 的方式 借用 h5 的方式即可实现上面的功能 添加业务域名 webview里面打开的地址 首
  • Mybatis操作数据库--通用

    选中 xml 右键 Junite 测试的时候 Test位于这个包中 import org junit jupiter api Test 根据条件进行查询总记录数 条件如果涉及到两个表的内容 你也就只写一个表里面的 select count
  • 简易版python爬虫--通过关键字爬取网页

    背景 帮同学写了个爬虫程序 特此记录 怕以后忘了 这里是爬取百度https www baidu com 不为什么 主要就是百度老实 能爬 爬着简单 爬着不犯法 关键字爬取基本模板 import requests from bs4 impor
  • Flutter学习四:Flutter开发基础(五)资源管理

    目录 0 引言 1 资源管理 1 1 指定 assets 1 2 Asset 变体 variant 1 3 加载 assets 1 3 1 加载文本 1 3 2 加载图片 1 3 2 1 声明分辨率相关的图片 1 3 2 2 加载图片 1
  • SIFT特征提取分析

    SIFT Scale invariant feature transform 是一种检测局部特征的算法 该算法通过求一幅图中的特征点 interest points or corner points 及其有关scale 和 orientat
  • 音视频开发(13)---视频监控系统必须知道的一些基础知识

    视频监控系统必须知道的一些基础知识 前言 在视频监控系统中 视频文件的传输带宽很重要 那视频文件的传输带宽怎么计算呢 首先给大家介绍几个名词 正文 1 比特率 比特率是指每秒传送的比特 bit 数 单位为bps BitPerSecond 比
  • XSS靶场第三关秘籍

    查看页面源代码 直接插入我们的代码进行尝试 没有弹窗 查看页面源代码 发现我们的 被实体编码了 这里把 改成
  • DBUtils工具类的使用方法详解

    DBUtils使用方法详解 目录 DBUtils使用方法详解 一 前言 二 JDBC介绍 1 基本概念 2 JDBC访问数据库的流程 三 DBUtils介绍 1 基本概念 2 配置文件 3 创建JDBCUtils类 4 实现对数据表的增删改
  • springboot整合knife4j,从此告别手写接口文档

    关于knife4j Knife4j的前身是swagger bootstrap ui 前身swagger bootstrap ui是一个纯swagger ui的ui皮肤项目 一开始项目初衷是为了写一个增强版本的swagger的前端ui 但是随
  • 递归求和

    用阶乘求1到100的和 思路 递归结束条件 n 1 递归公式 n sum n 1 include
  • 泛型T E K V ?

    Java泛型中E T K V等的含义 Java泛型中的标记符含义 E Element 在集合中使用 因为集合中存放的是元素 T Type Java 类 K Key 键 V Value 值 N Number 数值类型 表示不确定的java类型
  • 蓝牙模块调试总结(BLE\HC-05\HC-06\HC-01\MLT-BT05)

    最近在使用蓝牙模块与手机进行联合调试 遇到了一些问题 在此总结一下 1 蓝牙模块分类 MLT BT05 4 0蓝牙模块 指令集详细说明 MLT BT05 4 0 蓝牙串口模块指令为 Command 指令集 注 发 AT 指令时必须回车换行
  • 针对三角形问题,使用边界值分析法设计测试用例

    一 测试问题描述 输入三个整数a b c 分别作为三角形的三条边 通过程序判断这三条边是否能构成三角形 如果能构成三角形 则判断三角形的类型 等边三角形 等腰三角形 一般三角形 要求输入三个整数a b c 必须满足以下条件 1 a 200
  • Satck与Queue要点

    Satck Stack定义 核心接口 stack源码 栈的实现 静态数组实现栈 动态数组实现栈 链表实现栈 queue queue与stack queue的实现 Satck Stack定义 stack的特点是先进先出 与queue正好相反
  • 一个局域网中,不同网段的服务器能通信吗?

    文章目录 起步 环境说明 B ping A A ping B 子网的误判 感谢 起步 在一个局域网中存在两台服务器 A B A IP 192 168 211 110 NETMASK 255 255 255 0 B IP 192 168 21
  • QT 新手小白USBCAN 学习

    一 介绍CAN总线 CAN总线介绍 二 USBCAN总线 2 1 产品介绍 USBCAN 转换器模块实现了将 CAN 总线接口与 USB 接口进行相互转换 可以 简单方便的通过电脑监视 CAN 总线网络 同时可以实现工业现场数据稳定的双 向