admin管理员组

文章数量:1646314

第一篇文章 cpp

  • SLT
    • 哈希表
    • 排序
  • 关键字
  • Qt
    • 安装
      • Linux 下环境变量
    • linux 下动态库
    • QObject 内存管理机制
    • Qt 信号和槽函数
    • Qt 类方法
      • 坐标映射
      • QAbstractTableModel
    • 统计图
      • 条形图
      • Graphic(视图)
    • UI设计师
    • Qt线程使用事项
    • 使用常见问题
      • 编译提示
      • 线程
      • QBasicTimer::stop: Failed. Possibly trying to stop from a different thread
    • QtTcpsocket
    • server && client 通信
      • 非压缩打包数据传输
    • 桌面程序
    • 主窗口关闭时,如何将子窗口全部关闭
    • style设置
    • Qt嵌入式
  • windows 下
    • 启动bat
    • ntp windows时间到下位机
  • linux操作study
    • 基本命令
    • shell 脚本
  • git study
  • vs 2019
    • 问题总结
    • &&opecv3.4.6
    • vs2019 msvc windelopyqt 打包陈程序 执行 缺少VCRUNTIME140_1.DLL
    • x86和x64位程序环境配置
  • microsoft 相关
  • 电脑问题
    • 主机网络连接中没有vmnet0
    • 解决Ubuntu无法ping通Windows
    • ubuntu 共享目录问题

SLT

哈希表

  • map 的count函数
    map::count()
    用来对map的特定key进行计数,如果指定的key存在count()返回1,如果容器中不存在指定的key,返回0。
  • set
//删除操作,成功返回1,失败返回0
set1.erase(1); 
//删除操作,成功返回下一个pair的迭代器
set1.erase(set1.find(1));
//删除set1的所有元素,返回指向end的迭代器
set1.erase(set1.begin(), set1.end());

排序

函数:
template< class RandomIt, class Compare >
constexpr void sort( RandomIt first, RandomIt last, Compare comp );
参数:
first , last - 要排序的元素范围。
comp - 比较的函数,这里要满足compare的要求,如果希望从小到大,只需要return a<b;

关键字

  • explicit
    用途: C++中的explicit关键字只能用于修饰只有一个参数的类构造函数, 它的作用是表明该构造函数是显示的, 而非隐式的, 跟它相对应的另一个关键字是implicit, 意思是隐藏的,类构造函数默认情况下即声明为implicit(隐式).
    作用: explicit关键字的作用就是防止类构造函数的隐式自动转换
explicit CxxCopy(int arg);//只能显示调用, 避免隐士转换\
如,正确用法 CxxCopy ma(1); 错误用法 CxxCopy ma = 1;
  • Q_DECL_OVERRIDE
    用途 放在重载的虚函数后面
    作用 编译器时会检测当前函数如果不是虚函数,则报错。
// generate error if this doesn't actually override anything:
     virtual void MyWidget::paintEvent(QPaintEvent*) Q_DECL_OVERRIDE;

Qt

安装

Linux 下环境变量

//etc/profile
export QT_PATH=/home/zh/Qt5.14.2/5.14.2/gcc_64
export QT_CREATOR_PATH=/home/zh/Qt5.14.2/Tools/QtCreator
export LD_LIBRARY_PATH=$QT_PATH/lib:$LD_LIBRARY_PATH
export PATH=$PATH:$QT_PATH/bin:$QT_CREATOR_PATH/bin
保存后,重启source /etc/profile

linux 下动态库

//Qt 编译共享库后产生xxx.so.1.0.0 文件,使用方式如下步骤
//1.将xxx.so.1.0.0 放到linux系统非共享目录下
//2.新建软连接
libserverL.so -> libserverL.so.1.0.0
libserverL.so.1 -> libserverL.so.1.0.0
//3.在需要引入动态库项目.pro中添加库

LIBS += -L/xxx/lib -lserverL  //-L 后跟库文件所在目录 -l后跟库名称(不带前缀lib)
INCLUDEPATH += ../serverL     //将项目头文件路径包含进来
//3.项目中包含头文件
#include "serverL.h"

QObject 内存管理机制

QObject内部存在一个链表,保存父对象以及子对象,当父对象被delete时会将所有的子对象都析构。

图片来源:内存管理机制
QT的父子对象机制是在 QWidget和QOject中实现的。,如上图所示对界面的控件、QObject、QOWidget总结的很好。

总结,如下情况new出来的对象不需要手动delete.
1.Qt中new出来的对象如果指定父对象
2.Qt中addLayout、addWidget、addXXX等添加的布局或控件(相当指定了父对象为当前对象)
3.例外情况,new 的 setLayout对象本身需要手动删除。
以上总结的3部分如果不正确欢迎指正,非常感谢!

Qt 信号和槽函数

QMetaObject::Connection QObject::connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type = Qt::AutoConnection)

  • connect 第5个参数
    Qt::ConnectionType,有以下类型:
[1] Qt::AutoConnection //默认,如果发射器与接收器位于相同线程,则使用[2],否则使用[3]
[2] Qt::DirectConnection //槽函数在信号所在线程中直接执行,就像直接在当前线程调用了一个函数一样
[3] Qt::QueuedConnection//槽函数在接收器所在线程中执行,信号将进入接收线程所在的事件循环队列,当队列空闲时槽函数被调用
[4] Qt::BlockingQueuedConnection//接收器位于信号发射所在线程时禁用,否则app将进入死锁,与[3]相同,不同之处在于发送信号时线程阻塞,直到槽函数结束
[5] Qt::UniqueConnection// 可以结合上述任意一种采用OR使用,当设置后,如果connect已经存在,connect将失败。

Qt 类方法

坐标映射

例如 pWidget->mapToGlobal(QPoint(x,y));

即 把你在pWidget里面的坐标(x,y) 所表示的点. 用Global的坐标表示.

QAbstractTableModel

QAbstractTableModel 继承自 QAbstractItemModel,主要用于为 QTableView 提供相关接口,可以子类化该抽象类并实现相关接口(因为相关接口内的具体实现需要根据我们的需求进行定义)。
表格数据的展示
继承 QAbstractTableModel 后,至少要实现三个纯虚函数接口才能进行实例化;

  //获取行数|列数|单元格数据
virtual int rowCount(const QModelIndex &parent = QModelIndex()) const = 0;
virtual int columnCount(const QModelIndex &parent = QModelIndex()) const = 0;
virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const = 0;

– data()接口: view获取单元格数据(内容、颜色)时,会调用此接口。
@参数 QModelIndex :模型索引,提供了对信息的临时引用,可用于通过模型检索或修改数据,一般情况下我们只需要取他附带的行列值即可
@role :获取数据的类型,这是一个 Qt::ItemDataRole 枚举,一般用已有的 role 枚举就足够了。

 enum ItemDataRole {
        DisplayRole = 0,
        DecorationRole = 1,
        EditRole = 2,
        ToolTipRole = 3,
        StatusTipRole = 4,
        WhatsThisRole = 5,
        // Metadata
        FontRole = 6,
        TextAlignmentRole = 7,
        BackgroundRole = 8,
        ForegroundRole = 9,
#if QT_DEPRECATED_SINCE(5, 13) // ### Qt 6: remove me
        BackgroundColorRole Q_DECL_ENUMERATOR_DEPRECATED = BackgroundRole,
        TextColorRole Q_DECL_ENUMERATOR_DEPRECATED = ForegroundRole,
#endif
        CheckStateRole = 10,
        // Accessibility
        AccessibleTextRole = 11,
        AccessibleDescriptionRole = 12,
        // More general purpose
        SizeHintRole = 13,
        InitialSortOrderRole = 14,
        // Internal UiLib roles. Start worrying when public roles go that high.
        DisplayPropertyRole = 27,
        DecorationPropertyRole = 28,
        ToolTipPropertyRole = 29,
        StatusTipPropertyRole = 30,
        WhatsThisPropertyRole = 31,
        // Reserved
        UserRole = 0x0100
    };

@RETURN QVariant(是一种任意类型) :Qt中可以toXXX来转换,自定义类型可以用 convert 和 value 接口装箱拆箱。
使用案例:

//MyTableModel.h
#include <QAbstractTableModel>
struct ModelItem
{
   QString name;
   int sex;
   int age;
   int score;
};

class MyTableModel : public QAbstractTableModel
{
    Q_OBJECT

public:
    explicit MyTableModel(QObject *parent = nullptr);
    ~MyTableModel();
    void updateData(QList<ModelItem> fileRecodeList);

    //获取行数|列数|单元格数据
    virtual int rowCount(const QModelIndex &parent = QModelIndex()) const override;
    virtual int columnCount(const QModelIndex &parent = QModelIndex()) const override;
    virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
    //启用单元格编辑(设置单元格数据|[单元格的可操作性标志位,如可编辑,可选中等])
    bool setData(const QModelIndex &index, const QVariant &value,int role = Qt::EditRole) override;
    Qt::ItemFlags flags(const QModelIndex& index) const override;
private:
    //数据
    QList<ModelItem> modelData;
};
//MyTableModel.c
MyTableModel::MyTableModel(QObject *parent) :
    QAbstractTableModel(parent)
{
    modelData=QList<ModelItem>{
            {"aa",1,20,90},
            {"bb",1,23,91},
            {"cc",0,21,95},
        };
}

MyTableModel::~MyTableModel()
{

}

void MyTableModel::updateData(QList<ModelItem> fileRecodeList)
{
    modelData = fileRecodeList;
    beginResetModel();
    endResetModel();
}

int MyTableModel::rowCount(const QModelIndex &parent) const
{
    Q_UNUSED(parent);
    int tempRow = modelData.count();
    return tempRow;
}

int MyTableModel::columnCount(const QModelIndex &parent) const
{
    Q_UNUSED(parent);
    return 4;
}

QVariant MyTableModel::data(const QModelIndex &index, int role) const
{
    if(!index.isValid())
        return QVariant();
    if(role == Qt::DisplayRole || role == Qt::EditRole)
    {
        const int row=index.row();
        const int col = index.column();
        switch(col)
        {
        case 0:
            return modelData.at(row).name;
        case 1: return (modelData.at(row).sex==0)?"woman":"man";
        case 2:return modelData.at(row).age;
        case 3:return modelData.at(row).score;
        }
    }
    return QVariant();

}

bool MyTableModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
    qDebug()<<"setDate: "<<index<<" "<<value.toInt()<<" role:"<<role<<endl;
}

Qt::ItemFlags MyTableModel::flags(const QModelIndex &index) const
{
    if (!index.isValid())
        return Qt::NoItemFlags;
    return Qt::ItemIsEnabled|Qt::ItemIsSelectable|Qt::ItemIsEditable;
}
//使用时,将new的mode绑定在view上,后面mode的数据有更新,view都会相应更新
 m_mode = new MyTableModel(ui->tableView);
 ui->tableView->setModel(m_mode);

参考:
官方文档:https://doc.qt.io/qt-5/qabstracttablemodel.html
官方文档:https://doc.qt.io/qt-5/model-view-programming.html

统计图

条形图

三步骤:1.定义包含一类数据集合(可以定义多个不同数据类型的集合) 2.将这些不同类别的数据采用一种垂直堆积的柱状图表示(如果一个集合包含多个n个数据,则会有n个柱状图来表示) 3. 将所产生的柱状图添加到统计图表中 (可以为其创建对应的x和y轴)4.将chart 统计图表通过view来展示给用户

具体办法可以看Qt的帮助文档,关于QStackedBarSeries的example.

Graphic(视图)

Qt的图形视图框架,最核心的三个类为:QGraphicsScene、QGraphicsItem与QGraphicsView。
参考:https://blog.csdn/qq21497936/article/details/117660217

  • QGraphicScene
    描述

类提供了用于管理大量 2D 图形项的面。
该类用作QGraphicsItems的容器。它与QGraphicsView一起用于在二维面上可视化图形项,例如线条、矩形、文本,甚至自定义项。 QGraphicsScene是图形视图框架的一部分。
  QGraphicScene还提供了一些功能,可以让有效地确定项目的位置,以及确定在场景中任意区域内哪些项目可见。使用QGraphicsView小部件,可以可视化整个场景,或者放大并只查看场景的部分。

QGraphicsScene *pScene = new QGraphicsScene();
pScene->addText("Hello, world!");
QGraphicsView *pView = new QGraphicsView(pScene, this);


函数-作用

- 函数:setSceneRect()
f:设置场景的边界矩形(可视化区域矩形);项目可以放置在场景的任何位置,默认情况下,场景的大小是无限的。场景矩形仅用于内部记账,维护场景的项索引。
- items()
f: 查找确定项目位置; itemAt()可以获取到当前位置的某项
- 
  • QGraphicsView

QGraphicsView类提供一个窗口,用于显示QGraphicsScene的内容。

将已经创建的QGraphicsScene对象绑定到view(可以通过setScene()设置),当调用show()时,窗口将默认滚动到视图中心,并显示所有可见的项目,例如上面的”Hello world“.

  • QGraphicsItem
    简介

QGraphicsItem类是QGraphicsScene中所有图形项的基类
它为编写自己的自定义项目提供了轻量级的基础。这包括通过事件处理程序定义项的几何体、冲突检测、其绘制实现和项交互


Qt提供了一些标准的图形项:


- QGraphicsEllipseItem 提供椭圆项
- QGraphicsLineItem 提供直线项
- QGraphicsPathItem 提供任意路径项
- QGraphicsPixmapItem 提供pixmap项
- QGraphicsPolygonItem 提供多边形项
- QGraphicsRectItem 提供矩形项
- QGraphicsSimpleTextItem 提供简单的文本标签项
- QGraphicsTextItem 提供高级文本浏览器项

函数接口:

- setVisible()
f: 设置项是否可见,隐藏项目也会隐藏其子项;setEnable() 可以启用或禁止项,如果禁用某个项目,它的所有子项也将被禁用;
default(默认情况下),项目既可见又启用;

UI设计师

  • 关于QMenu* 相关
    |||||
    |–|–|–|–|

Qt线程使用事项

参考:Qt线程常见问题参考外链图片转存失败,源站可能有防盗

使用常见问题

编译提示

  • 搜索OPenssl ,下载软件包,找到libeay32.dll、ssleay32.dll

    将两个sll放置执行文件同目录下即可解决(如果不能解决尝试换其他版本试试)

线程

- 子线程不能操作UI
- 子线程中哪些对象属于子线程
- 如何查看是否实现了多线程
  • 程序异常退出总结
    – client连接服务端socket断开时,服务端此时点击stop,程序异常退出
    服务端问题原因:
    1 服务端采用threadPool管理所有新建的线程,并且设置了线程退出时进行资源释放
    2 服务端所有新建线程都保存在一个set集合中
    因此:当socket断开连接时,根据服务端工作线程设定原理,工作线程会退出(此时该线程对象也会被销毁释放),但是服务端功能设定,点击stop时,会遍历set集合,使用之前保存的线程对象,但是由于set集合内部某些对象已经被销毁的,此时在使用就造成了程序异常。
  • QRunnable
    – 关于setAutoDelete()函数true,能否让资源释放问题(能否启用析构)
    Qt文档指出:如果设置为true, 当run结束后,QThreadPool 将自动的delete this runnable.
    验证得出结论:
    1. runnable->setAutoDelete(bool),true:线程结束,自动析构,false:需要程序员手动delete
RunnableThread *runnable = new  RunnableThread;
runnable->setSockDescriptor(socketDescriptor);
runnable->setAutoDelete(true);
runnableMgr.append(runnable);
pThreadPool->start(runnable);

2. runnable->setAutoDelete(bool) 默认情况是true,另外就算不调用该函数,线程结束时也同样执行析构。

  • QThread
    如果出现如下错误,请考虑:
QObject: Cannot create children for a parent that is in a different thread.
(Parent is TcpServer(0x15c4266e270), parent's thread is QThread(0x15c4266b870), current thread is QThread(0x15c4266b8c0)

– 如果将某个线程中的obj通过 move移动到了另一个线程,那么该obj则禁止直接在当前线程中直接使用;
– 在子线程中创建对象时,只能使用子线程(可以理解为run())的对象的指针对其初始化,禁止采用run所属的parent(就是构造函数的this)初始化;-- 当然如果采用moveTothread, 则可以采用this初始化,我的理解是当执行move后,当前对象所有成员都移动到了子线程中,this不例外;

QBasicTimer::stop: Failed. Possibly trying to stop from a different thread

/*出现此问题的原因或许为:在子线程中创建(包括movetoThread到线程的对象),该对象对主线程(ui线程)拿来直接使用了。
*/

QtTcpsocket

  • readyRead()信号触发时机

server && client 通信

非压缩打包数据传输

  • send
    为了保证数据能够正确发送,同时避免粘包,可以将数据打包(数据块size+数据流);
struct MESSAGE_HEADER
{
    uint dataLen;      /*数据长度*/
};
struct MESSAGE_DATA
{
	MESSAGE_HEADER header;
	uchar data[1];
}

1 将data大小与自身封装到mess包中
2 调用接口开始发送mess
int sendMessage(socket, mess, len);
封装发送数据接口(参数:socket, mess, len),返回值为实际发送的数据长度。

接口内部逻辑:每次做多发送n字节,当实际发送的字节数与mess数据len相等时发送成功。
  • recv

桌面程序

  • 窗体移动-问题记录
    无边框鼠标移动时,窗口位置跑偏
    问题现象: 当鼠标点击按钮,或者在窗口的非拖动区域(比如指定窗口可拖动区域为this->y() < 100 )内,然后移动鼠标到可拖动区域,此时主窗体整体位置跑偏。
    问题原因: 在mouse 关于mousepress、mouserelease、mousemove三个虚函数中重新获取并更新主窗口的位置,由于在非窗口可拖动区域内 ,鼠标点击时,此时的位置没有被捕获到,然而当鼠标移动到可拖动区域后,需要用之前记录的位置来计算现在新的位置,但是之前的位置压根没有,因此整个窗体位置跑偏。
    解决思路: 在进行位置更新前,现判断之前的位置是否获取到,如果没有的话就不进行位置更新。

主窗口关闭时,如何将子窗口全部关闭

setAttribute(Qt::WA_QuitOnClose, false);
创建子窗口对象时,不要指定this为parent,否则子窗体会直接画在父窗口上,为null就好;

  • 所有子窗体Qt::WA_QuitOnClose属性至true,则参与主程序退出流程,因此主窗口关闭时子窗体不会退出;
  • 所有子窗体Qt::WA_QuitOnClose属性至false,则不参与主程序退出流程,因此主窗口关闭时子窗体则退出;

style设置

  • 为一个按钮设置背景图,同时背景图的大小也可以调整,方式如下
    QPixmap pinmap1(":/source/pic/001.png");
    ui->closeWinBtn->setIcon(QIcon(pinmap1));
    ui->closeWinBtn->setIconSize(QSize(33, 32));
    ui->closeWinBtn->setStyleSheet("border: 0px");
//或者使用styleSheet ,通过border-image让图片自适应控件大小(注意语法,写错了可能不生效)
	QString styleSheetMini = QString("QPushButton{border-image:url(%1); background-color:transparent;border: none;}QPushButton:hover{background-color:#505050;}")
	.arg(":/source/pic/001.png");
	ui->miniWinBtn->setStyleSheet(styleSheetMini);

Qt嵌入式

  • arm板可能没有相关的库文件,通过如下方法可以实现arm的移植
    Q: 如何编译main.c,并将编译后的文件移植到arm板也能够正常运行
    A: 采用静态编译,将所需要的库文件继承到可执行文件中
    如;arm-linux-gcc main.c -static
    移植到arm板,运行结果:hello word!,如下图所示:
  • 移植qt

下载并配置交叉编译器(arm gcc/g++)、下载linux Qt
采用qmake make
将可执行文件移植到arm板
默认的qmake 环境变量配置文件:sudo gedit /usr/lib/x86_64-linux-gnu/qt-default/qtchooser/default.conf

前期准备:
– 交叉编译工具
arm-linux-gnueabihf-gcc :不同arm板提供的可能有所差异,使用时尽量使用对应的。
– Qt源码版本
地址:Qt源码
选择single 版本的 qt-everywhere-src-5.14.2.tar.xz,将其放置在ubuntu 根目录或家目录下解压,tar -xvf qt-everywhere-src-5.14.2.tar.xz

注意:Qt 5.7 以后版本,不在支持Windows xp.

  1. 安装交叉ARM编译器
    如果选择了arm sdk下的交叉编译器,copy其所在路径配置环境变量。
  • 环境变量
    vim ~/.bashrc
    PATH=$PATH:/…/bin
    保存退出, source ~/.bashrc ,在任意路径下输入arm- 进行tab自动缩进,如果能检测到arm-linux-*, 表示配置成功。
  1. 交叉编译Qt5.14.2
    cd qt-everywhere-src-5.14.2
  • 将qtbase/mkspecs/linux-arm-gnueabi-g++ 拷贝一份副本。
  • 修改gedit qtbase/mkspecs/linux-arm-gnueabi-g++/qmake.conf,如下:
#
# qmake configuration for building with arm-linux-gnueabi-g++
#
 
MAKEFILE_GENERATOR      = UNIX
CONFIG                 += incremental
QMAKE_INCREMENTAL_STYLE = sublib
 
QT_QPA_DEFAULT_PLATFORM = linux #eglfs
QMAKE_CFLAGS_RELEASE += -O2 -march=armv7-a
QMAKE_CXXFLAGS_RELEASE += -O2 -march=armv7-a
 
 
include(../common/linux.conf)
include(../common/gcc-base-unix.conf)
include(../common/g++-unix.conf)
 
# modifications to g++.conf ,最好用绝对路径
QMAKE_CC                = /usr/local/arm/arm-gcc/bin/arm-linux-gnueabihf-gcc
QMAKE_CXX               = /usr/local/arm/arm-gcc/bin/arm-linux-gnueabihf-g++
QMAKE_LINK              = /usr/local/arm/arm-gcc/bin/arm-linux-gnueabihf-g++
QMAKE_LINK_SHLIB        = /usr/local/arm/arm-gcc/bin/arm-linux-gnueabihf-g++
 
# modifications to linux.conf
QMAKE_AR                = /usr/local/arm/arm-gcc/bin/arm-linux-gnueabihf-ar cqs
QMAKE_OBJCOPY           = /usr/local/arm/arm-gcc/bin/arm-linux-gnueabihf-objcopy
QMAKE_NM                = /usr/local/arm/arm-gcc/bin/arm-linux-gnueabihf-nm -P
QMAKE_STRIP             = /usr/local/arm/arm-gcc/bin/arm-linux-gnueabihf-strip
load(qt_config)
  • 创建一个脚本(autoConfigure.sh),用于生成Makefile,执行命令:
    gedit autoConfigure.sh -> chmod +x autoConfigure.sh -> sudo ./autoConfigure.sh
#!/bin/sh
./configure \
-v \
-prefix /opt/qt-5.14.2 \
-release \
-opensource \
-no-accessibility \
-make libs \
-xplatform linux-arm-gnueabi-g++ \
-optimized-qmake \
-pch \
-qt-sql-sqlite \
-qt-zlib \
-tslib \
-skip qtdeclarative \
-no-opengl \
-no-sse2 \
-no-openssl \
-no-nis \
-no-cups \
-no-glib \
-no-pkg-config \
-no-separate-debug-info \
-I/opt/tslib1.4/include -L/opt/tslib1.4/lib

解释:

-prefix /opt/qt-5.14.2 : 编译完成后安装的地址;
-tslib:代表QT对触摸板的支持,不需要的话直接删除
-skip qtdeclarative :不加的话,后面make可能会出错

Project MESSAGE: Hunspell not found! Spell correction will not be available.
Project ERROR: Unknown module(s) in QT: quick
Makefile:44: recipe for target 'sub-virtualkeyboard-make_first' failed
make[2]: *** [sub-virtualkeyboard-make_first] Error 3
 
或者
 
sh:1:python:not found
Project ERROR:Building QtQml requires Python.
Makefile:44: recipe for target 'module-qtdeclarative-install_subtargets' failed
make: *** [module-qtdeclarative-install_subtargets] Error 3

参考网上帖子:https://forum.qt.io/topic/71552/how-to-install-and-build-qt5-7-everywhere-for-beaglebone-black-os-debian

  • 编译和安装
    编译: make -j8 ;在Qt源码根目录下直行
    安装:sudo make install ;完成后检查 /opt/qt-5.14.2 ,出现如下文件表示成功:
  • 配置Qt交叉编译环境
    配置默认qmake编译器。

    检查是否配置成功:
  • 交叉编译Qt程序
    分别执行qmake、make,可以查看到如下可执行文件:
  • 运行
    经过交叉编译后的可执行程序移植到开发板环境后,运行起来还需如下步骤:
  • 移植适用于该开发板环境的Qt库
  • 配置环境变量
  • 启动程序的脚本
  • Qt库
    之前make install好的qt目录下,lib动态库拷贝到开发板 /usr/lib(记得新建文件夹)

  • 环境变量

export QTDIR=/usr/lib/
export QTDIR5=/usr/lib/Qt5.14.2
export LD_LIBRARY_PATH=/lib:$QTDIR:$QTDIR5:$LD_LIBRARY_PATH
export QT_QWS_FONTDIR=$QTDIR/fonts/
#export QWS_DISPLAY=LinuxFb:/dev/fb0
#export QWS_SIZE=800x480
export POINTERCAL_FILE=/etc/pointercal
export QWS_DISPLAY="LinuxFb:mmWidth80:mmHeight160:0"
export QT_PLUGIN_PATH=$QTDIR/plugins/
export QWS_MOUSE_PROTO=Tslib:/dev/input/event0
export PATH=$QTDIR:$PATH
  • 运行脚本
    run.sh
#!/bin/sh

source /app/global_env
/app/porttest
/app/RadarServer

完成上述配置后,运行sh脚本即可。

windows 下

启动bat

  • 遇到的坑,cmd.exe /c,/c后未加空格直接调用.bat,导致bat中新建文件txt失败
QString exePath = QCoreApplication::applicationDirPath() + "/bat/sftp.bat";
QStringList argList;
argList << "/c " << exePath .replace('/', '\\') ; // /c后需要加“ ”,避免后续某些问题
process.start("cmd.exe", argList);
int retCode = process.waitForFinished();

ntp windows时间到下位机

让Linux下位机跟Windows上位机自动时间同步
https://blog.csdn/happen23/article/details/118898265
https://wwwblogs/zhangwc/p/9830653.html

linux操作study

基本命令

  • 内存
//linux查看内存占用情况(top、free、ps)
top  //实时显示系统cpu、个进程资源占用  ,q 退出
[参数]
-p  pid  //某进程cpu\mem 等动态情况

[举例]
top | grep 'RadarServer'  // top | grep pid
------------------------------
ps  //进程状态
[参数]
-ef //是用标准的格式显示所有进程
-ef | grep nana   // 查看某一个进程所占用的内存
  • NetCat (nc 命令)
//server
nc -l port > file.bin //将port监听到的数据写入file.bin文件
//client 
nc ip port < file.bin
//查看二进制数据
nc file.bin | xxd
  • SCP进行文件传输
//1、从本地将文件传输到服务器
//scp [本地文件的路径][服务器用户名]@[服务器地址]:[服务器上存放文件的路径]
scp /Users/zz/Desktop/test.png root@192.168.1.109:/
//2、从本地将文件夹传输到服务器
scp -r /Users/zz/Desktop/test root@192.168.1.1:/

  • netstat
/*
-t-显示TCP端口。
-u -显示UDP端口。
-n -显示数字地址而不是解析主机。
-l -仅显示监听端口。
-p -显示侦听器进程的PID和名称。仅当你以root用户或 sudo 用户身份运行命令时,才会显示此信息。
*/
sudo netstat -tunlp
/*
请使用 grep命令,查找特定端口(22)侦听的进程
*/
sudo netstat -tnlp | grep :22 
  • 进程相关
gnome-system-monitor // 打开任务管理器
netstat -tunl | grep [port] //查看port端口相关的进程

shell 脚本

  • Linux Shell基础 多个命令中的分号’;‘、与’&&’ 、 或’||’
    在 Bash 中,如果需要让多条命令按顺序执行,则有这样方法
多命令执行符格 式作 用
命令1 ; 命令2多条命令顺序执行,命令之间没有任何逻辑关系
&&命令1 && 命令2如果命令1正确执行( ? = 0 ) ,则命令 2 才会执行如果命令 1 执行不正确( ?=0),则命令2才会执行如果命令1执行不正确( ?=0),则命令2才会执行如果命令1执行不正确(?≠0),则命令2不会执行
II命令1 II 命令2如果命令1执行不正确( ? ≠ 0 ) ,则命令 2 才会执行如果命令 1 正确执行( ?≠0),则命令2才会执行如果命令1正确执行( ?=0),则命令2才会执行如果命令1正确执行(?=0),则命令2不会执行
  • Linux Shell 1>/dev/null 2>&1 含义
//echo log > /dev/null 2>&1
/dev/null :代表空设备文件
>  :代表重定向到哪里,例如:echo "123" > /home/123.txt
1  :表示stdout标准输出,系统默认值是1,所以">/dev/null"等同于"1>/dev/null"
2  :表示stderr标准错误
&  :表示等同于的意思,2>&1,表示2的输出重定向等同于1

1 > /dev/null 2>&1 语句含义:
1 > /dev/null : 首先表示标准输出重定向到空设备文件,也就是不输出任何信息到终端,说白了就是不显示任何信息。
2>&1 :接着,标准错误输出重定向(等同于)标准输出,因为之前标准输出已经重定向到了空设备文件,所以标准错误输出也重定向到空设备文件。
  • while 循环
//while循环语法结构
while 表达式
    do
        command...
    done

while  [ 1 -eq 1 ] 或者 (( 2 > 1 ))
  do
     command
     command
     ...
 done
//当条件测试成立(必须为真),返回值为0才能执行循环体

git study

  • 基本命令
1.git push  // 默认是git push origin 当前分支名
2.git branch// 查看本地分支
git branch -r //查看远程分支
3.git commit --amend //上一次commit后,在未进行合入之前,发现代码存在问题需要修改,--amend可以修改,不产生新的commit
  • 撤销本地commit

两种方式
1.原来提交的代码都在,不会被撤销
2.你最新的commit命令下修改的内容将完全被撤销

  • 仅仅撤销commit 的提交,奔流本地代码的修改
    git reset HEAD~N //N为所需撤销的前几次

  • 撤销commit提交,同时本地所修改的代码完全恢复到commit之前的状态
    git reset --hard HEAD^N

  • git 删除修改

//查看本地所有变动过的文件,并不会执行递归删除
git clean -nxdf  
//经上述确认确需删除后,执行一下命令
git checkout . && git clean -xdf

n: 不实际删除,仅仅将本地的修改展开
x: 执行
d: 递归删除dir文件
f: 实施,强迫
  • git diff

比较文件在暂存区和工作区的差异

//尚未缓存的工作区改动
git diff 
//查看已缓存的改动
git diff --cached
//查看已缓存的与未缓存的所有改动
git diff HEAD
//显示两条提交记录的差异
git diff SHA1 SHA1
  • git stash
    目的:可以将当前branch没有commit 的代码先暂存起来,完毕后git status会发现当前分支很干净,此时就可以解决线上的其他问题,之后再通过git apply恢复之前的codes ,继续之前的开发。
    相关用法:
git stash save "change description"; //将当前分支的变更保存到堆栈缓冲区,添加描述为了后续恢复时分辨方便
git stash apply ;//应用某个存储,此存储并不会从列表中删除,默认使用第一个存储stash@{0};
git stash apply stash@{$num};
git stash drop stash@{$num}; //丢弃stash@{$num}存储,从stash list 列表中删除。
git stash clear ; //将所有的stash缓存删除,谨慎操作。 
git stash pop stash@{$num}://将stash 缓存列表中的记录恢复 ,同时从stash 缓存堆栈中删除,默认恢复第一条记录stash@{0}(就是最新save的记录)
git stash show stash@{$num}; //查看那些文件做了改动,默认显示第一个存储
git stash show stash@{$num} -p ; //查看改动了的文件的具体那些内容改动了,就像git diff一样
  • git checkout
git checkout  -b <branch>  ;//创建并切换到一个新的分支
git switch -c <branch> ; 
  • git issue
    – 切换分支后,上一分支的变动被带到了切换后的分支(明明还未合并?)
    description:当前分支的变动没有加到git的版本控制,因此切换分支后,变动的内容也被带到了新分支。
    resolve: 1. git stash暂存后再切换;2mit后再切换

vs 2019

在vs2019 中安装Qt插件


上述下载完成后,弹出的安装小窗口进行Qt插件的安装。

问题总结

  • 打开qt项目时,提示:
错误		[QtRunWork] Error starting process D:\vs2015\5.9.1\msvc2015_64\bin\uic.exe: 系统找不到指定的文件。	RvdSystem	C:\Users\hao\AppData\Local\QtMsBuild\qt_globals.targets


解决办法:找到工程目录下.user文件,将对应路径修改为正确的路径即可

&&opecv3.4.6

  • debug模式下配置
    a. vc++ 包含目录,如下:

    库目录,如下:

    b. 连接器 ,输入->附加依赖项(release的话是opencv_world346.lib)

  • VS2019配置opencv3.4.13时无法找到opencv_world3413d.dll
    首先找到opencv的安装路径,然后找到vc15的bin目录,我的路径是E:\Project directory\lib\opencv3.4.1\opencv\build\x64\vc15\bin

    将这3个*.dll这三个文件复制到(推荐)C:\Windows\System32中(exe所在目录下也可以),问题解决。

vs2019 msvc windelopyqt 打包陈程序 执行 缺少VCRUNTIME140_1.DLL

解决方案:打开vs2019 项目-属性-C/C+±代码生成-运行库:
多线程Dll(/MD) 改为多线程(/MT),然后编译运行

将生成的exe文件放入“多线程Dll(/MD) ”所产生的Qt依赖库打包目录下,成功解决。
解决原因:多线程MT编译出来的文件运行时不需要加载三方dll, 运行效率高一点。而多线程dll则需要在运行时加载第三方dll,因此会稍微慢一点。

x86和x64位程序环境配置

如果当前只有x64(或x86),想添加x86为当前编译环境,则选择X86 version

注意:Version的命名,填写完路径后,在填写名称,然后带年纪保存,错误的命名会有提示,防止后续因为无效的名称导致编译失败(如qmake路径和x86或x64不匹配)

新建添加x86-win32,如果version选择后已经产生x86选项,则跳过[1] - [3]步骤。
[1]

[2]

[3] x86只是名称, 如果不从x64复制,则后续的Modules 就是空的

[4] 配置为win32, x86 – > win32
[5] Qt Installation 选择 x86对应的

完成以上配置后,即可去完成x86环境下程序的编译。

microsoft 相关

microsoft 开发人员社区

电脑问题

主机网络连接中没有vmnet0


需要在虚拟机首选项,操作如下:

点击应用,确认后即可。
当然,可能会出现明明勾选了,再次打开后有恢复为未勾选,ccleaner去修复注册表的内容,第一步先清理下内存占用,第二步扫描下注册表漏洞并修复下。

清理完后,点击注册表Registry,点击扫描,然后点击选定问题进行修复。

完成以上操作,然后重新选定虚拟机选项,就可以正常了。

解决Ubuntu无法ping通Windows

windows 可以ping ubuntu,


windows 无法ping ubuntu,

【1】右键单击屏幕右下角Internet访问 --》打开“网络和Internet”设置。
【2】Windows防火墙设置 --》 高级设置。
【3】双击入站规则 --》 找到文件和打印机共享(回显请求 - ICMPv4-In)
【4】双击文件和打印机共享(回显请求 - ICMPv4-In) --》常规–》打钩已启用
【5】应用 --》 确定 --》 关闭

验证,如下:

ubuntu 共享目录问题

  • 重启后,共享文件不见了
    ubuntu 16.04.7 ,
//安装虚拟工具
sudo apt install open-vm-tools
//打开fstab
sudo vim /etc/fstab
//添加如下内容,然后重启
.host:/ /mnt/hgfs fuse.vmhgfs-fuse allow_other 0 0
//wq  ,reboot

本文标签: 以及其他技术QT