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(一般方法)

//详细可参考  https://blog.csdn.net/foruok/article/details/32698603?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522160282957719725255540435%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=160282957719725255540435&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-4-32698603.pc_first_rank_v2_rank_v28&utm_term=Qt+QML&spm=1018.2118.3001.4187

 

//我使用的是 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,图片无法调用//或者其他未知名错误

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

////



 

posted @ 2020-09-10 13:24  小城熊儿  阅读(701)  评论(0编辑  收藏  举报