qt 笔记
再次接触qt,这次得细致的学习学习
1 项目有问题可以先清除项目,再执行qmake,再三角
2 报lnk2019等,可以先想想是不是dll库没有加进来,可以用右键的方式添加lib或者dll库,系统在.pro中自动生成代码,不会出错,
然后将dll库加入到exe所在文件中,(release或者debug文件时不一样的)
3 qt对位操作非常不友好,c与运算不起作用,我有个地方需要将字符串转成16进制输出
eg:a对应的ascii应该是97对应16进制应该是61,我需要61,可以直接用.tohex文件输出.
eg: QByteArray info="aa"; info.toHex()的输出结果就是6161
4 combox加下拉复选框
(1)界面上加入一个combox按钮,然后引入头文件
#include <QCheckBox>
(2)在头文件中引入
#include <QListWidget>
(3)头文件加入
QListWidget *m_workshopListWidget;
(4)在cpp中构造文件加入
m_workshopListWidget = new QListWidget(this);
m_workshopListWidget->setObjectName(QString("listWidget_wkshop"));
for(int i=0; i< 5; i++)
{
QListWidgetItem *item = new QListWidgetItem();
m_workshopListWidget->addItem(item);
QCheckBox *chkBox = new QCheckBox();
chkBox->setText("test1");
m_workshopListWidget->setItemWidget(item, chkBox);
connect(chkBox,SIGNAL(stateChanged(int)),this,SLOT(slot_stateChanged()));
}
ui->comboBox->setModel(m_workshopListWidget->model());
ui->comboBox->setView(m_workshopListWidget);
ui->comboBox->setEditable(true);
(5)添加槽函数
void Widget::slot_stateChanged()
{
QString str ;
for ( int i= 0 ; i<5 ; i++ )
{
QListWidgetItem *item = m_workshopListWidget->item(i);
QCheckBox *box = (QCheckBox*)m_workshopListWidget->itemWidget(item);
if ( box->checkState() == Qt::Checked )
{
str += box->text();
str += ",";
}
}
str = str.mid(0,str.size()-1);
if(str == QString(""))
{
str = QStringLiteral("选择车间");
}
}
不一定能用,但是一定可以显示,然后按照自己的想法修改成自己想要的就可以了
5 char*,QString,QByteArray转换 参考https://blog.csdn.net/qq_33485434/article/details/78790285
QString转char*
QString str; char* ch; QByteArray ba = str.toLatin1(); ch=ba.data();
6 qt使用strcpy竟然越界了,之前使用都没事儿,这个问题倒腾我半个小时,还没找到问题,请教别人才知道是strcpy存在野指针问题,可能导致内存越界,最终结局就是程序崩溃.这个是隐藏bug,以后不使用strcpy统一使用strncpy来代替
对于qt有个更好的代替方式,使用qstrncpy
7 设置qlineedit区间范围
ui->dataNoGasCloseDays->setValidator(new QIntValidator(0,255,this));
8 设置路径为相对位置
imagesPath = QCoreApplication::applicationDirPath().left(QCoreApplication::applicationDirPath().lastIndexOf("/"))+"/images/";
ui->comIcon->setPixmap(QPixmap(imagesPath+"comDown.png"));
9 设置主界面背景图
QPalette pal = this->palette();
pal.setBrush(QPalette::Background,QBrush(QPixmap(imagesPath+"bg.jpg").scaled(this->size())));
this->setPalette(pal);
10 注册信息在main中判断,之后在register中利用定时器再次判断可以实现功能注册码错误打开软件直接提示,不用定时器也可以,不过qmessage窗体会不按照规定移动,至今未找到接解决方法
11 注册表使用方法
QSettings *reg = new QSettings("HKEY_CURRENT_USER\\Software\\Tools\\meterTools", QSettings::NativeFormat);//确定路径(key)
reg->setValue(ui->machineCode->text(),ui->registerCode->text());//确定注册的key的值名称和值数据
QString registervalue = reg->value(ui->machineCode->text()).toString();//读取key的值名称对应的值数据,然后用某个函数判断值名称和值数据对不对,不对则报错,对则继续.
//处理判断逻辑
delete reg;//最后删掉,节省空间
12 注册表中包含了系统和硬件之间的链接,很重要,被删了,系统可能无法启动,由一层一层的key组成.
13 QMessageBox有个很神奇的地方,显示中文会乱码,查资料可能是程序编码不一致,使用QStringLiteral可能导致中文乱码,我代码界面输入四个汉字,实际界面显示六个字乱码,
推测怀疑代码使用三字节编译一个汉字,而显示界面使用两字节显示一个汉字,结果出现六个汉字QStringLiteral修改成QString::fromUtf8竟然好了,了,了(之前是不行的)
QMessageBox::information(this,QString::fromUtf8("注册错误"),QString::fromUtf8("注册错误注册码过期,请输入最新注册码"));
14 近几天做qt与html通讯的事情,发现一个奇怪的地方就是在html上点击一个发送按钮之后,html页面总是会刷新,因为经验少不知道是qt的问题还是HTML的问题,找了半天,和部门同事争执好一会儿
然后我偶然觉得,应该是html的问题,于是就html界面点击后页面刷新为线索进行搜索,发现html页面中button标签在点击后会自动刷新,解决方式有三种(亲测第二种有效)
参考 https://blog.csdn.net/wjf1433993341/article/details/85782283
15 qt与html通讯需要qwebengine和channel,主要还是用信号和槽.,还得用msvc来编译.具体编译可以有时间出一个blog
16 qt快捷键, ctrl+shift+r 可以实现修改全体变量
右键点击 Refactor->在xxx.c 可以实现快速将.h中定义的函数,在xxx.c中实现
17
//QT设置在制定的第三个字符处插入"\n"
int tempos = res.indexOf(';',QString(list[0]).length()+QString(list[1]).length()+QString(list[2]).length()+2);
res.insert(tempos+1,"\n\n");
18 字符串的科学计数法,转double类型科学计数法 还有qstring可以直接转换double,无论科学计数法还是一般的都可以(我痛苦的找其他方法,结果以下方法说c++11有问题,无奈自己写了一个)
#include <sstream>
using namespace std;
double d;
stringstream("1.23456e+003")>>d;//d=1234.56
19 qt程序打包 可执行文件的图标要用ico格式图片,使用 http://pic.55.la/ 可以在线转化格式,然后将图片放到images文件夹放到有可执行文件.exe的文件夹中
(我直接放在了realease中),然后在pro中加上 RC_ICONS = images/logo.ico ,注意.ico的文件名字不要写错了(=_=')
至于封包,我用简单的7z做辅助制作的,在7z压缩时,记得使用LZMA压缩算法,不然那,使用 SfxMaker7Zip 打包后使用会出问题的(>.<)
可以参考这个,很全 https://www.jb51.net/softjc/62678.html
20 qt在stylesheet中设置边框属性 QGroupBox{border-width:1px;border-style:solid;border-color:lightGray;}
21 记得有if就一定会有else选项,尽量加上,不然运行起来可能会有意想不到的bug, eg程序乱跳
22 设置lineeidt只能按照自己想要的格式输入,有三种选择,int double 正则.有个bug,如果只想输入数字,用int没问题,但是如果想让数字按照指定格式显示,考虑过用正则,但是觉得别扭,
可以用int或double限制只输入数字,然后用editingfinished信号对输入的数字重新设置.(科学计数法也可以识别)
//控制输入格式
#include <QRegExp> //按照指定正则输入
#include <QRegExpValidator>
#include <QValidator> //指定整数或者小数
#include <float.h> //有double的最大值
//初始化只能输入数字
ui->dataMaxMoney->setValidator(new QDoubleValidator(0.00,1000000000.00,2,this));
//输入完成后进行格式化
ui->dataMaxMoney->setText(QString::number(ui->dataMaxMoney->text().toDouble(),'f',2));
23 令人崩溃的错误提示:程序中有一段需要显示中文,使用了QString::fromlocal8bits,不行,使用了QStringLiteral也不行,报错都一样
错误一:new line constant错误
错误二:定义时,少了")"
我仔细检查了好几遍,我写的没错,头疼崩溃好久,硬着头皮看百度,有某位仁兄提到了,中文几十个汉子和偶数和汉字报错问题,确认是qt文件编码的问题,将编码方式修改为utf8
还有个bom,之前没选对竟然也能用,这次修改为"如果编码是UTF-8则添加"竟然编译通过了,,,,,,,,哈哈哈哈哈,,,,想要复现bug,竟然还没办法复现了,,,,哈哈哈哈,,=_=|
记得看下pro文件编码格式最好和文件编码格式保持一致(说多了都是泪*_*)
24 今天又踩了一个大坑 时间转字符串,我精确到毫秒原本是20位,我写了个加密方式,然后写进去注册表,但是这一块时不时的报错,并且毫无规律可言,
最后写测试函数发现 QString tem2 = QDateTime::currentDateTime().toString("yyyyMMddhhmmsszz"); 这个语句转换出来的字符串位数不是固定的20位,
字符长度如果最后的zz末尾有0的话,会自动被省略,(~_~||)太可怕了,因此需要特定长度的话,就需要自己手动添加个字符补充了
25 qt槽函数可能被多次执行(-_-|)这个也是坑,按照网上给的方法,加上Qt::unique........没记住,但是没用,后来修改程序逻辑了
26 qt如果在类声明中使用了QObject宏,那么就不能使用template,会报错
27 使用Qthread记得,添加头文件,记得写继承关系,记得修改构造函数.记得添加run方法(public就好)
#include <processthreadsapi.h> //其中有个sleep函数,属于秒级延时
#include <QThread>
28 记得将类方法在设计之初,就考虑下扩展性问题.早发现早享受.
29 程序核心最好用c++或者c语言来写,可移植性很好
30 qt另外一种定时器是Qobject类型,使用我觉得更方便一些,主要就三个函数,不用申请空间,时间毫秒级别
int temtimerID1 ;
// int QObject::startTimer ( int interval ) ; //正常情况下ID应该保存为全局变量
// void QObject::timerEvent ( QTimerEvent * event );//在这个里面判断时不时这个ID,做相应的处理
// void QObject::killTimer ( int id ); //通过ID杀死当前定时器
31 qt在位数不够的时候填充字符串
QString temstr = ui->dataUserId->text();
if(temstr.length()<16){ temstr = QString("%1%2").arg(0,15-temstr.length(),10,QLatin1Char('0')).arg(temstr);}
ui->dataUserId->setText(temstr);
32 QByteArray里面存储的都是char类型的数据,直接用转数据计算,如果数据大于127,(eg:151,会被转换为-105),因此必须要注意,强制转换为unsigned char才能正确显示.
33 QString转u8 * bytes (unsigned char *)binData.toLatin1().data() binData是QString类型,一定记得不要忘了*
(unsigned char )是将数据转换 (unsigned char *)是将对应地址上的数据转换
34 Qmessage报错register\threadchecktime.cpp(129): error C2665: 'QMessageBox::information': none of the 4 overloads could convert all the argument types
参考别人的解决方法: 4个重载中没有一个可以转换所有参数类型。通过不断测试与查阅资料发现是this指针的问题。因为information静态函数第一个参数类型为QWidget* parent。而我的ftp.cpp里面没有创建窗口,把this传给information,编译器无法确定其父窗口是谁。解决办法就是将this改成0,表示我就是顶层窗口,解决问题。
35 昨天遇到了一个麻烦,一个bug说我uchar定义重复,这个在全文检索,看看自己哪里定义重复了,修改重复的部分,然后就可以解决问题了
36 一个说 fatal error C1189: #error: "No Target Architecture" 追踪后是这个地方 参考 https://www.cnblogs.com/pandamohist/p/13685190.html
总结就是缺少了头文件,在引用 #include <processthreadsapi.h>之前要加上 #include <windows.h>
37 近日开始研究qt开发安卓应用,推荐学习下qt on android这一本书,内容浅显易懂,写作方式也很人性化,虽然用人qt5.2但是里面的内容还是差不多的,
在执行安装命令之前,一定要检查配置环境是否安装ok,不然程序报错能让你怀疑人生.具体的安装过程qt on android 上有
注意:如果你的qt版本比较老,ndk最好用16以前的,不要用最新的,因为最新的不是g++编译的,但是qt是g++编译的,
亲测qt5.9.2使用 ndk-r16b没问题.qt14用最新的没问题.
38 记得执行之前,可能有两个qmake选项都执行下.
39 在c中直接返回数组类型的指针,在语法上没问题,但是在qt上却出现bug,如果不在函数中添加一个debug可能就会出现乱码,
解决方法:传递一个数组变量进来(指针).可以完美解决这个问题.
40 qt控制安卓的传感器,据说有很多,但是有什么,,,,,,,不知道,就比如我想用手机上的红外功能,但是网上找不到相关资料,qt 安卓 蓝牙 到时有,功夫不负有心人,在qt帮助中我找到了所有的传感器相关的类,附赠蓝牙开发: https://www.cnblogs.com/sigma0/p/5769527.html
41 今天遇到一个头疼的bug: QWaitCondition: Destroyed while threads are still waiting
bug原因是我在一个定时器里面处理初始化程序,但是这个程序比较耗时,大于定时器定时的1秒钟,解决办法,代码首句就是关闭定时器timershow->stop();,最后有需要再打开
42 对于代码要尽可能的精简,如果已经发现是在粘贴复制了,那就说明代码结构有问题,可以先划分变化点和固定点,然后将固定点组合成框架,将变化点组合成变量,变量可以使用结构体,或者类.使用类的方式网络上很多,但是使用结构体作为变化变量传参的,每一个说的明白的,我参考c++primerplus中第六版217页的案例自己只做了一些小改动,成功的运用结构体传参,具体方式如下截图 (运行在qt环境下)
具体调用
43 int *p = -1;会报错,可以这样写int p[]={-1};
44 今天安装android studio测试红外,遇到一个奇葩的问题就是gradle总是在打开新项目就更新,我尝试了网上所有办法,,木用,,,,,,最后想起我手动配置过一个gradle,就修改了下这个配置,居然好了,,,,,,,,,,,,,如下,(注意,得新建一个项目,然后替换gradle-wrapper.properties,build.gradle(app),build.gradle(project)这三个文件,如下(我这里有两个app,所以多了))
45 今天贴一些,qt调用手机传感器的一些代码,(一般情况下,在qt调用安卓代码之前,安卓activity的oncreate函数就已经运行了,这一点尤其需要注意,如果想在调用之前做些什么,可以重写这一点java代码,)
//一下案例可以直接粘贴使用
//qt调用安卓源码//头文件,有需要的,可以全加就加上,无所谓
#include <QAndroidJniEnvironment>
#include <QtAndroidExtras/QAndroidJniObject>
#include <QtAndroid>
#include <jni.h>
#include <QGyroscope>//陀螺仪
#include <QAccelerometer>//加速度传感器数据
#include <QLightSensor>//光线
#include <QMagnetometer>
#include <QProximitySensor>
#include <QRotationSensor>
#include <QGeoPositionInfoSource>
#include <QGeoCoordinate>
#include <QGeoPositionInfo>
#include <QAccelerometer>
//陀螺仪
QGyroscope *gyroscope;
QGyroscopeReading *reader;
gyroscope = new QGyroscope(this);
gyroscope->start();
reader = gyroscope->reading();
qreal x = reader->x();
qreal y = reader->y();
qreal z = reader->z();
QString tem = QString("gyroscope:\nx:%1\ny:%2\nz:%3\n").arg(x).arg(y).arg(z);
ui->textEdit->insertPlainText(tem);
//震动OK
QAndroidJniEnvironment env;
QAndroidJniObject activity = QtAndroid::androidActivity();
QAndroidJniObject name = QAndroidJniObject::getStaticObjectField(
"android/content/Context",
"VIBRATOR_SERVICE",
"Ljava/lang/String;"
);
//CHECK_EXCEPTION();
QAndroidJniObject vibrateService = activity.callObjectMethod(
"getSystemService",
"(Ljava/lang/String;)Ljava/lang/Object;",
name.object<jstring>());
//CHECK_EXCEPTION();//if (env->ExceptionCheck()) {env->ExceptionClear();}
jlong duration = 200;
vibrateService.callMethod<void>("vibrate", "(J)V", duration);
//CHECK_EXCEPTION();
//屏幕旋转ok
QAndroidJniEnvironment env;
QAndroidJniObject activity = QtAndroid::androidActivity();
jint orient = activity.callMethod<jint>(
"getRequestedOrientation"
);
//if (env->ExceptionCheck()) {env->ExceptionClear();}
if(orient == 1)
{
orient = 0;
}
else
{
orient = 1;
}
activity.callMethod<void>(
"setRequestedOrientation",
"(I)V", orient);
//光线偶尔OK
QLightSensor *lightSensor;
QLightReading *lightReading;
lightSensor = new QLightSensor(this);
lightSensor->start();
lightReading = lightSensor->reading();
qreal lux = lightReading->lux();
QString tem = QString("lightSensor:\nx:%1\n").arg(lux);
ui->textEdit->insertPlainText(tem);
45 qt写安卓代码,并通过jni调用//如果想要调用系统传感器就必须写activity,并且activity在qt启动时会自动创建,在qt自己写的代码中不能重复创建activity(坑)
静态方法无法调getSystemService方法,因为它是非静态方法.
如果想在qt中直接写java代码并调用可以使用jni来掉,qt中有一个案例notification可以直接实现这个功能.此处简要介绍如何搭建过程
//新建项目
//选android,我一般为了偷懒,只用realease
//然后创建模板
(此处尚有争议,我在创建的时候,用不通方式尝试了十几次,创建出来的java程序就是无法被正确调用,无奈只好将notification中一整套的信息拿过来用,可以正常调用java代码,此时在创建create template时候注意不要覆盖以前的内容.)
//创建好了之后会出现安卓开发的manifest文件,此文件用于开启常见的手机传感器权限,我这里使用的是震动和红外(红外直接没有选项,得手动添加),(因为使用jni直接调用安卓代码有很多地方太麻烦,不如直接在java中做好封装,用string传递信息进行数据传递更方便.)(具体有哪些传感器,可以在android stdio中查看.)
其中ir需要手动添加,可以用记事本或者notepad++打开AndroidManifest.xml,添加以下代码,位置如图(右键,在explore中显示可以快速打开所在文件夹)
<!-- 红外遥控 -->
<uses-permission android:name="android.permission.TRANSMIT_IR" />
<!-- 仅在支持红外的设备上运行 -->
<uses-feature android:name="android.hardware.ConsumerIrManager" android:required="true" />
<!--开启震动-->
<uses-permission android:name="android.permission.VIBRATE"/>
//或者,add按钮也可以.(ir貌似不可以,必须手动添加)
//然后修改java代码,此处有个java函数调用使用的是非静态方法,因此,要重新创建一个非静态方法.(注意不能用静态方法调用非静态方法.),为了减少初始化对象次数,我这里用了一个小窍门,先声明一个静态变量,初始化为null,使用时候先判断为null,则初始化,否则跳过,如果在多线程,此处可考虑用双重校验锁,可以的话+volatile最为保险(此处单线程,没考虑那么多)
具体代码如下
package org.qtproject.example.notification; import android.app.Notification; import android.app.NotificationManager; import android.content.Context; import android.hardware.ConsumerIrManager; public class NotificationClient extends org.qtproject.qt5.android.bindings.QtActivity { private static NotificationManager m_notificationManager; private static Notification.Builder m_builder; private static NotificationClient m_instance; public NotificationClient() { m_instance = this; } public static void notify(String s) { if (m_notificationManager == null) { m_notificationManager = (NotificationManager)m_instance.getSystemService(Context.NOTIFICATION_SERVICE); m_builder = new Notification.Builder(m_instance); m_builder.setSmallIcon(R.drawable.icon); m_builder.setContentTitle("A message from Qt!"); } m_builder.setContentText(s); m_notificationManager.notify(1, m_builder.build()); } public void irtest() { int zeroL = 560; int zeroH = 560; int oneL = 560; int oneH = 1578; ConsumerIrManager mCIR = (ConsumerIrManager) getSystemService(Context.CONSUMER_IR_SERVICE); if (!mCIR.hasIrEmitter()) {return;} int[] back = { //start 4400,4400, //L //0xFA 1111 1010 oneL,oneH,oneL,oneH,oneL,oneH,oneL,oneH, oneL,oneH,zeroL,zeroH,oneL,oneH,zeroL,zeroH, //0x04 0000 0100 zeroL,zeroH,zeroL,zeroH,zeroL,zeroH,zeroL,zeroH, zeroL,zeroH,oneL,oneH,zeroL,zeroH,zeroL,zeroH, //0 0000 0000 zeroL,zeroH,zeroL,zeroH,zeroL,zeroH,zeroL,zeroH, zeroL,zeroH,zeroL,zeroH,zeroL,zeroH,zeroL,zeroH, //0 0000 0000 zeroL,zeroH,zeroL,zeroH,zeroL,zeroH,zeroL,zeroH, zeroL,zeroH,zeroL,zeroH,zeroL,zeroH,zeroL,zeroH, //0x2B 0010 1011 zeroL,zeroH,zeroL,zeroH,oneL,oneH,zeroL,zeroH, oneL,oneH,zeroL,zeroH,oneL,oneH,oneL,oneH, //end 2200,6600,1100 //end }; mCIR.transmit(38000, back); } }
//(此处有坑,我qt中设置是utf-8 bom方式编码,目的是为了避免qt中书写中文是区分奇数个汉子和偶数个汉子的错误,但是qt中java可用utf8编码,使用utf-8 bom方式系统就会爆出莫名bug,可以在别处转为utf8编码可解决问题,我用的notepad++,不要用qt编辑,编就会出错,可恶的windows)
//为了达到的演示的目的,此处用qml和c++通讯,在qml界面调用c++代码,c++通过jni调用java代码,达到演示效果
//qml与c++通讯有四种方式,最简单的是信号与槽,这种通用的方式,//然后注册QML可用类型//然后在QML中导入类型//然后使用
余下的三个方法是 Q_PROPERTY(动态注入,强大,但是有点繁琐) Q_ENUMS(可注册枚举) Q_INVOKABLE(一般方法)
//我使用的是 QT QML跨平台移动APP编程 中提供的方法,简单方便,此处c++代码中注册了一个方法和一个变量代码如下
.h
#ifndef VIEWIR_H #define VIEWIR_H #include <QObject> class ViewIr : public QObject { Q_OBJECT Q_PROPERTY(QString userName READ userName WRITE setUserName NOTIFY userNameChanged) public: explicit ViewIr(QObject *parent = nullptr); QString userName(); void setUserName(const QString &userName); Q_INVOKABLE void changeName(const QString &userName); signals: void userNameChanged(); private: QString m_userName; }; #endif // VIEWIR_H
.cpp
#include <QtAndroidExtras/QAndroidJniObject> #include <QtAndroid> #include "viewir.h" ViewIr::ViewIr(QObject *parent) : QObject(parent) { } QString ViewIr::userName() { return m_userName; } void ViewIr::setUserName(const QString &userName) { if(userName == m_userName)return; m_userName = userName; emit userNameChanged(); } void ViewIr::changeName(const QString &userName) { setUserName(userName); QAndroidJniObject javaNotification = QAndroidJniObject::fromString(userName); // QAndroidJniObject::callStaticMethod<void>("org/qtproject/example/notification/NotificationClient", // "notify", // "(Ljava/lang/String;)V", // javaNotification.object<jstring>()); QAndroidJniObject activity = QtAndroid::androidActivity(); activity.callMethod<void>("irtest"); }
main.cpp
#include <QGuiApplication> #include <QQmlApplicationEngine> #include <QQmlContext> #include "viewir.h" int main(int argc, char *argv[]) { QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QGuiApplication app(argc, argv); QQmlApplicationEngine engine; //invoke view QQmlContext *ctx = engine.rootContext(); ViewIr v;v.setUserName("to young to simple"); ctx->setContextProperty("view",&v); const QUrl url(QStringLiteral("qrc:/main.qml")); QObject::connect(&engine, &QQmlApplicationEngine::objectCreated, &app, [url](QObject *obj, const QUrl &objUrl) { if (!obj && url == objUrl) QCoreApplication::exit(-1); }, Qt::QueuedConnection); engine.load(url); return app.exec(); }
main.qml
import QtQuick 2.12 import QtQuick.Controls 2.12 import QtQuick.Layouts 1.12 ApplicationWindow { id: applicationWindow visible: true width: 540 height: 960 Label{ id: label text: view.userName horizontalAlignment: Text.AlignHCenter anchors.centerIn: parent } TextField{ id: textField text: "修改属性值" horizontalAlignment: Text.AlignHCenter anchors.top: label.bottom anchors.topMargin: 20 anchors.horizontalCenter: label.horizontalCenter onTextChanged: { view.userName = text; } } TextField{ id: textField2 text: "修改方法" horizontalAlignment: Text.AlignHCenter anchors.top: textField.bottom anchors.topMargin: 20 anchors.horizontalCenter: label.horizontalCenter onTextChanged: { view.changeName(text); } } }
pro
QT += quick androidextras 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). Refer to the documentation for the # deprecated API 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 \ viewir.cpp RESOURCES += qml.qrc # Additional import path used to resolve QML modules in Qt Creator's code model QML_IMPORT_PATH = # Additional import path used to resolve QML modules just for Qt Quick Designer QML_DESIGNER_IMPORT_PATH = # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target DISTFILES += \ android-sources/AndroidManifest.xml \ android-sources/build.gradle \ android-sources/gradle/wrapper/gradle-wrapper.jar \ android-sources/gradle/wrapper/gradle-wrapper.properties \ android-sources/gradlew \ android-sources/gradlew.bat \ android-sources/res/values/libs.xml \ android-sources/src/org/qtproject/example/notification/NotificationClient.java ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android-sources HEADERS += \ viewir.h
//注意,在第二个输入框修改时候,触发java代码
//具体的下载地址
https://files.cnblogs.com/files/RYSBlog/irAndroid.zip
//构建项目时候,注意安卓设备,此处demo是有关于android红外的,我特意将震动效果也加进来,方便没有红外的也可以测试
//建议不要用影子构建,可能会有意外发生,eg,图片无法调用//或者其他未知名错误
////