新建窗口(无论有没有UI)需要注意的
要重视窗口继承的父类是什么,如果需要连接和定义槽函数就必须继承QObject及其派生类, 个别容器控件需要界面类是继承QWidget的
QT中,类要支持信号与槽机制,需要继承自QObject并在头文件开头添加Q_OBJECT宏.
在ubuntu把qt打包好的程序添加桌面快捷方式打开
1、尝试使用ln -s Desktop/demo2/demo2 Desktop/Robot创建软连接(并重命名),失败,双击执行Robot提示找不到可执行的路径,原文件也是脚本不能双击打开,创建的软连接也不能双击打开
2、创建桌面图标,创建一个robot.desktop文件,写入以下代码:
[Desktop Entry]
Version=1.0
Type=Application
Name=My Shortcut # 修改成自己的名称
Comment=This is my shortcut # 可以修改
Exec=/path/to/your/program # 修改
Icon=/path/to/your/icon # 修改
Terminal=false
Categories=Utility # 可以修改
将以上文件夹放到/usr/share/applications/
sudo mv robot.desktop /usr/share/applications/
执行
sudo update-desktop-database
就会刷新到应用菜单栏, 我们假设程序不需要以root身份运行。如果需要以root身份运行程序,那么需要将”Terminal=false”更改为”Terminal=true”,以在打开终端窗口时自动获取root权限。
此时桌面是没有的,将/usr/share/applications/robot.desktop复制到桌面,双击执行就可以变成一个快捷方式
信号槽传输结构体
也需要注册为元类型才能传输
头文件中:Q_DECLARE_METATYPE(heartBeat);
源文件中:qRegisterMetaType
error: no match for ‘operator==‘ (operand types are ‘const TaskInfo‘ and ‘const TaskInfo‘) if(n->t() ==t)
原因分析:结构体TaskInfo,由于QList在调用removeOne函数时需要查找到对应内容进行删除,因此需要进行对比,struct类型是没有对比的,所以需要进行重载解决该问题。
解决办法:
error: no match for ‘operator==’没有匹配的==判断函数,说明编译器不知道TaskInfo结构体怎么比较算是两个对象相等。在TaskInfo结构体中重载==运算符
struct TaskInfo {
QString taskID;
QString deviceName;
QString deviceID;
int status;
QDateTime cyc_time;//选定的时间
int cyc_mode;//0就一次不循环,1就是每天,7就是每七天,30就是每月
QString xyz; // x-y,x-y,x-y
//编写==重载判断两个TaskInfo相等
bool operator==(const TaskInfo &p)
{
return (this->xyz == p.xyz) && (this->deviceID == p.deviceID);
}
};
Python websocket 模块 ImportError: cannot import name ‘WebSocketApp‘
问题解决
运行 from websocket import WebSocketApp 语句时,
报错 ImportError: cannot import name ‘WebSocketApp’
查看发现,我的电脑中有两个 websocket 相关的包,分别是版本是:
websocket 0.2.1
websocket-client 0.56.0
websocket 0.2.1 这个包我忘了是什么时候安装的,但我知道,我代码中使用的是 websocket-client 0.56.0 包。
所以,我卸载了两个包并重新安装了 websocket-client
sudo pip3 uninstall websocket
sudo pip3 uninstall websocket-client
sudo pip3 install websocket-client
此时,bug 得到了修复。
我做了个实验,再次安装了 websocket 包
sudo pip3 install websocket
果然 bug 得到了复现。
实验发现,安装 websocket-client 后,dist-packages 中新出现了 websocket 和 websocket_client-0.56.0.dist-info 两个文件夹。
安装 websocket 后,dist-packages 中多出了 websocket-0.2.1.dist-info 文件夹,并且 websocket 文件夹中的文件(如:init等)被覆写。
所以,我们使用的时候找不到 websocket_client 0.56.0 这个包,从而出现以上 bug。
参考
https://stackoverflow.com/questions/37442193/cannot-import-websocketapp-form-websocket-in-python
2021-08-02 补充
本文中的 websocket 库是一个未实现的库,没有描述信息,没有发布者等。
pypi地址 https://pypi.org/project/websocket/
本文中的 websocket-client 库是一个简单好用的同步的 websocket 的客户端的库,基于回调的方式使用。
pypi地址: https://pypi.org/project/websocket-client/
GitHub地址: https://github.com/websocket-client/websocket-client
文档地址: https://websocket-client.readthedocs.io/en/latest/
websockets 库也是一个很火的库,在 github 上已经有 3.5k 的星了,能用于实现服务器端和客户端,他是基于 asyncio (Python 的标准异步 I/O 框架) 实现的,提供一个基于协程的 API 来管理 Python 中的 WebSocket 连接。 因为基于 asyncio 所以只能在 Python3 中使用。
pypi地址: https://pypi.org/project/websockets/
GitHub地址: https://github.com/aaugustin/websockets
文档地址: https://websockets.readthedocs.io/en/stable/
————————————————
原文链接:https://blog.csdn.net/tz_zs/article/details/96423813
以上操作依旧没有解决:
检查文件名是否和websocket重名
QT中编写SQL语句需要注意的是,需要填写字符串类型时需要加“ ”,需要整数时不能加任务引号,需要DateTime类型时也是字符型,需要用标准格式输入
字符串和数字示例:
QString queryStr = R”(UPDATE device set status = %1 where deviceID = “%2”;)”;
query.exec(queryStr.arg(status).arg(deviceID))
DateTime示例:
QString queryStr = R”(UPDATE task set “cyc_time” = “%1” where taskID = “%2” )”;
query.exec(queryStr.arg(nextTime.toString(“yyyy-MM-dd HH:mm:ss.zzz”),TaskID)
QString arg属性解释
//用后面依次替换前面,后面的类型确保都是Qstring即可。
QString strs=QString("%1 %2 %3").arg("a","b","c");//输出a b c
QString strs=QString("%1 %2 %3 %4 %5").arg("a","b","c").arg("d","e");//输出a b c d e
//单个逐个替换
QString strs=QString("%1 %2 %3").arg("a").arg("b").arg("c");//输出a b c
QString str = QString("%1 %2").arg("%1World").arg("Hello");//HelloWorld %2
//注意,int也可以为long、double等
str = QString("%1").arg(63, 0, 16);//3f 十进制63的十六进制为3f
double d = 3.1415926;
str = QString("delta: %1").arg(d, 0, 'g',4);
//g表示精度是4,即整数+小数长度为4 输出为3.142
总结:想几个一组就几个一组,只要保证每组内的数据类型是一致的字符串都要是字符串,数字都要是数字(int,long,double),混合数据类型就会报错
new要写到信号槽的前面!!!!!!!!!!!!!!!!!!!!
指针对象请务必实例化,并删除
装入归档文件时出现了一个错误;Linux中无法打开exe文件
在Linux中,无法直接运行Windows的.exe文件,因为它们是不同的操作系统上的不同二进制文件格式。如果您想在Linux上运行一个Windows的.exe文件,有以下几种方法可以尝试:
\1. 使用Wine:Wine是一个兼容层,使得在Linux上可以运行Windows应用程序。您可以按照安装Wine的过程,并使用Wine来运行您的.exe文件。请注意,并非所有的Windows应用程序都能在Wine中正常运行。
\2. 使用虚拟机:您可以在Linux上安装虚拟机软件,如VMware或VirtualBox,然后在虚拟机中运行Windows操作系统,并在其中运行您的.exe文件。
请注意,在运行.exe文件之前,您必须确保已经安装了相关的库和依赖项。您可能需要在Linux上手动安装这些依赖项,以确保能够正确运行.exe文件。
写入文件(会产生4个字节的多余字节)
QFile writefile("1.dat");//如果文件不存在,则创建该文件。路径在执行文件的上一级路径下。
writefile.open(QIODevice::ReadWrite);
QDataStream out(&writefile);
//以下为5中写文件的方式,有些会在文件开头出多写入4个字节表示长度,有些不会,需要仔细区分!
out << ba;//这种方式会在生成的文件一开始多处4个字节,表示QDataStream的长度
out.writeBytes(ba.data(),ba.size());//这种方式也会在文件头多出4个字节
out.writeRawData(ba.data(),ba.size());//这种方式保存的数据为实际ba中的内容,不会有任何多余字节
writefile.write(ba);//这种方式也不会有多余字节
writefile.write(ba.data(),ba.size());//这种方式也不会有多余字节
writefile.close();
出现错误error: undefined reference to `vtable for TaskDispatch’
- 类的构造函数、析构函数没有进行定义(只在.h中声明没定义)
- 头文件中出现了一些Qt的关键词,如Q_OBJECT、signals等,这时候要将头文件也放到CMakeLists.txt的add_executable中,不然不会将这些关键词编译,也就没有办法正确生成类了。如果使用Qt工程,头文件则要放到.pro文件的HEADERS中。
“undefined reference to `vtable for’…”错误.
在使用qt开发新项目时候,添加新的类是非常频繁的操作。有时候,会不小心跳过一些关键步骤,导致出现一些问题。例如“undefined reference to `vtable for”错误就很常见。
QT中,类要支持信号与槽机制,需要继承自QObject并在头文件开头添加Q_OBJECT宏.
如果使用QtCreator创建类时,没有选择继承自QObject类或其子类,而在创建后手工修改继承自QObject并手工添加Q_OBJECT宏,则在编译时有可能会出现”undefined reference to `vtable for’…”错误.
如果添加后,没有马上编译,而是编写了很多业务代码后编译,才发现qt给你报了大量错误。
这时怎么处理呢?
解决方法:
方法一:重新执行qmake(2021,08.03);
方法二:把新创建的类从项目中移除(注意不要从磁盘上删除),然后再添加进工程,QtCreator就会重新解析此类,再编译就不再会出现上述错误.
方法三:qtcreator有时候会抽风,实在不行就人工删除编译的中间文件,重新编译;
使用网络传输QFile
- QFile转成QByteArray : QByteArray ba = file.readAll()
- 使用QByteArray传输
- QByteArray转成QFile : file.write(ba)
QDateTime转换
QDateTime a;
QDate b(2019,09,09);
QTime c(01,02,03,111);
a.setDate(b);
a.setTime(c);
Qt程序打包好报错:无法定位程序输入点 __gxx_personality_v0 于动态链接库
需要将qt/5.12.0/mingw64/bin/libstdc+±6.dll 放到打包程序的根目录中;如果上面方法不生效:本地如果有多个/libstdc+±6.dll,将指定的编译环境的环境变量往上调
将QVector在Qt信号槽中传输的方法(eg.传输QVector):
#include
#include
//声明QVector封装成一个元类型
Q_DECLARE_METATYPE(QVector);
class database
{
private:
//声明一个QVector对象
QVector searchResult;
//声明一个QVarit对象
QVariant searReasult_for_device;
};
class database::database()
{
//在构造函数中注册元类型
qRegisterMetaType("QVariant");
};
//在函数体中,将QVector封装到QVariant中
searReasult_for_device.setValue(searchResult);
//就可以发送
emit s_searchResult_for_device(searReasult_for_device);
#include
QVector vecData;
void classname::show(QVariant varData)
{
vecData = varData.value>();
//...接下来就可以对QVector进行操作
}
时间戳转Datetime格式
QString dateTimeStamp = datetime.fromTime_t(static_cast
在QProcess中调用涉及到后安装软件的指令,必须得指明路径才行
QT QMessageBox定时退出
QMessageBox *box = new QMessageBox(QMessageBox::Information,tr(“你好”),tr(“你好”));
QTimer::singleShot(1500,box,SLOT(accept())); //也可将accept改为close
box->exec();//box->show();都可以
监听的 Socket 和真正用来传数据的 Socket 是两个,一个叫作监听Socket,一个叫作已连接 Socket
Qt Debug可以编译通过,但是无法通过release编译:
1、可能缺少可文件,需要仔细查找
2、可以在(.pro)文件中加入QMAKE_CXXFLAGS += -Werror=return-type
并进入Debug模式运行,就会打印出错误
时刻关注Vector访问的下标是否越界,每次在访问下标的时候都要进行越界判断
QT视频播放错误:DirectShowPlayerService::doRender: Unresolved error code 80040266
默认使用winfdows的解码器有些视频打不开,需要下载解码器,安装到qt根目录即可
QSocketNotifier: Socket notifiers cannot be enabled or disabled from another thread报错解决:
背景及原因解释:
我在Maindow里实例化了一个WsClient的对象,获取到文件路径后直接调用这个对的方法“发送文件”;在QWsClient这个类里创建的QWebSocket socket,同时”发送文件“的函数中也用到socket,这样创建是在WsClient使用是在MainWindow,所以报错。
解决:通过信号槽将获取到的文件路径发送到WsClient里执行“发送文件”,就解决了。(补充1:我并没有添加任何子线程,仍有一个疑惑就是我并没有在不同线程中分开建立何使用socket,我依旧认为此时的MainWindow和WsClient是一个线程上运行的,都属于主线程,开发的项目是在Android上运行的,不知道会不会因为Android的机制认为是不同线程,请大佬解答了)(补充2:同在MainWindow类里调用wsClient自定义方法中也是用了socket.errorstring()并没有报错,sendTextMessage()也不会报错,只有sendBinaryMessage()方法报错)
信号槽发送数据
创建一个子线程对象是主线程的工作.也就是说在对象在哪个线程被实例化就属于哪个线程.利用movetothread函数可以将对象转移至另外的线程.
使用connect之后,槽函数默认执行在槽函数所在线程,若改变connect函数的第五个参数,比如设为Qt::DirectConnection,可让槽函数在信号所在线程执行.
Android通过USB安装安装包
Android程序,在手机连接USB“调试模式”下,找到系统../android-sdk-windows/platform-tools(该目录可以添加到环境变量)这个目录可以使用命令
1、查看设备ID
adb devices
2、发送安装包
adb -s C80220601028 install F:\build-untitled-Android_for_armeabi_v7a_Clang_Qt_5_12_0_for_Android_ARMv7-Debug\android-build\build\outputs\apk\debug\qtA.apk
QT项目打包
1、把release编译好后的.exe文件复制到一个qtexefile(任意命名)文件夹下,C:\Qt\Qt5.12.0\5.12.0\mingw73_64\bin(例)添加到系统环境变量
2、在qtexefile文件夹下,powershell(我没有成功,但是使用cmd就成功了)运行windployte server.exe
QT开发Android项目获取(android.permission.WRITE_EXTERNAL_STORAGE可以替换)权限
QtAndroid::PermissionResult r = QtAndroid::checkPermission("android.permission.WRITE_EXTERNAL_STORAGE");
if(r == QtAndroid::PermissionResult::Denied) {
QtAndroid::requestPermissionsSync( QStringList() << "android.permission.WRITE_EXTERNAL_STORAGE" );
r = QtAndroid::checkPermission("android.permission.WRITE_EXTERNAL_STORAGE");
if(r == QtAndroid::PermissionResult::Denied) {
return false;
}
}
进入Android系统:adb shell
安卓APP相关路径
系统应用安装位置:/system/app
系统特权应用安装位置:/system/priv-app
用户应用安装位置:/data/app
APP私有数据目录(访问需要Root权限):
/data/data
/data/user/
/data/user_de/
APP共享数据目录(Android11以上需要使用”文档”应用进行访问或授权,在shell权限下或使用MTP连接电脑,可直接访问):
/data/media/
/storage/self/primary/Android/data
/sdcard/Android/data