1.设置默认竖屏/横屏显示

先**编译一下项目**,在编译的debug文件下的android-build里,有个AndroidManifest.xml文件(如下图)
在这里插入图片描述
拷贝一份到项目文件下随便新建的一个文件夹里(我这里叫AndroidSource,src这里不用管,是我后来自己创建的)
在这里插入图片描述
然后在qt里右键项目->and new,把刚刚拷贝的xml文件添加进来(如下图),此时othere files里就有xml文件了
在这里插入图片描述
然后在.pro文件里加上这句

ANDROID_PACKAGE_SOURCE_DIR = $$PWD/AndroidSource  //PWD/后面就是你新建文件夹的名字

然后右键xml文件,选择用普通文本编辑器打开(就是记事本方式打开),找到下图中的这一行
在这里插入图片描述

portrait就是竖屏
landscape是横屏

2.全屏显示设置、状态栏设置

参考:https://blog.csdn.net/qq_21078557/article/details/85226809

3.设置toast悬浮提示

参考:https://blog.csdn.net/qq_37603131/article/details/89609539
3.1 自建仿toast方式

顾名思义,这个就是自己建一个仿真toast的类,在其中写好实现的效果,然后外部需要调用是直接调用这个类的成员函数即可,在此帖最后会放上一个链接,包含源代码,需要的可自行下载参考。(注:此方法也是参考其他帖子下载内容源代码)

创建好子类文件
在这里插入图片描述
代码分别如下

stoast.h

// 仿Android的toast提示框
// 适宜将此类实现为多线程下的单例模式
 
#ifndef STOAST_H
#define STOAST_H
 
#ifdef Q_OS_WIN32  //Windows 下使用VC++编译器的utf-8字符集解析源码
    #if _MSC_VER  >=1600
        #pragma execution_character_set("utf-8")
    #endif
#endif
 
 SToast 部分用到
#include <QWidget>
#include <QLabel>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QTimer>
#include <QPainter>
#include <QEvent>
#include <QDesktopWidget>
#include <QApplication>
#include <QPropertyAnimation>
 
 SingleTonSToast 部分用到
#include <QMutex>
#include <QReadWriteLock>
#include <QAtomicPointer>
#include <QDebug>
 
class SToast : public QWidget
{
    Q_OBJECT
public:
    explicit SToast(QWidget *parent = 0);
    ~SToast();
 
    int duration()const;
    void SetDuration(int msec);  //持续显示时间,ms
 
signals:
 
public slots:
    void setMessageVDuration(QString msg, int msecDisplayTime=2500);  //消息显示多少毫秒消失
 
protected:
    void paintEvent(QPaintEvent *event);
 
private:
    QHBoxLayout *hLayout;
    QVBoxLayout *vLayout;
    QLabel *label;   //提示文字
    QLabel *labIcon; //图标
    int msDuration;  //单位ms
    QTimer durationTimer;
    QPropertyAnimation *animation;
 
    void fadeInAnimation();   //淡出动画
    void fadeOutAnimation();  //淡入动画
 
private slots:
    void timeOver();  //定时器超时响应函数
    void fadeInAnimationFinished();  //淡出动画结束响应槽
};
 
class SingleTonSToast
{
public:
    /*! \brief 用于获得SingleTonSToast实例,使用单例模式。
     *  \return SingleTonSToast实例的引用。
     */
    static /*SingleTonSToast*/SToast &getInstance(void)
    {
#ifndef Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE
        if(!QAtomicPointer</*SingleTonSToast*/SToast>::isTestAndSetNative())  //运行时检测
            qDebug() << "SingleTonSToast类 Error: TestAndSetNative not supported!";
#endif
        //使用双重检测。
        /*! testAndSetOrders操作保证在原子操作前和后的的内存访问
         * 不会被重新排序。
         */
        if(instance.testAndSetOrdered(0, 0)){  //第一次检测
            QMutexLocker locker(&mutex);//加互斥锁。
            instance.testAndSetOrdered(0, new /*SingleTonSToast*/SToast);//第二次检测。
        }
 
        return *instance;
    }
 
private:
    SingleTonSToast();  //禁止构造函数。
    SingleTonSToast(const SingleTonSToast &);//禁止拷贝构造函数。
    SingleTonSToast & operator=(const SingleTonSToast &);//禁止赋值拷贝函数。
 
    QReadWriteLock internalMutex;   //函数使用的读写锁。
    static QMutex mutex;            //实例互斥锁。
    static QAtomicPointer</*SingleTonSToast*/SToast> instance;  /*!<使用原子指针,默认初始化为0。*/
};
 
#endif // STOAST_H

stoast.cpp

#include "stoast.h"
 
//静态成员变量初始化。
QMutex SingleTonSToast::mutex;
QAtomicPointer</*SingleTon*/SToast> SingleTonSToast::instance = 0;
 
 
SToast::SToast(QWidget *parent) : QWidget(parent)
{
    //初始化成员
    msDuration = 5000;
    animation = new QPropertyAnimation(this, "windowOpacity");
 
    //初始化窗口属性
    setWindowOpacity(0);  //达到比较好的淡出效果,需要将窗口设置完全透明,否则会有卡顿的效果
    this->setAttribute(Qt::WA_TranslucentBackground,true);  //设置背景透明
    setWindowFlags(Qt::CustomizeWindowHint|Qt::FramelessWindowHint|Qt::Tool|Qt::WindowStaysOnTopHint);
    setStyleSheet("background: black;color: white;border-radius: 5px;");
 
    //窗口大小及位置属性
    setFixedSize(700,100);  //设置为固定窗口大小达到禁止调节窗口大小
    // Unbtun下有当前桌面扩展,显示的桌面只是逻辑上的一部分,所以看不到居中的效果
    //move((QApplication::desktop()->width() - width())/2,(QApplication::desktop()->height() - height())/2);
    // 此方方法可以解决居中显示的问题
    QRect curDesktopRc = QApplication::desktop()->screenGeometry(this);  //获取显示本窗口的屏幕区域
    move((curDesktopRc.width() - width())/2, (curDesktopRc.height() - height())/8*7); //屏幕居下显示
 
    //图标、字容器初始化
    //labIcon = new QLabel();
    label = new QLabel();
    label->setFont(QFont("宋体",16));
    label->setAlignment(Qt::AlignCenter);
    label->adjustSize();        //自适应文本
    //label->setWordWrap(true);   //自动折行
    label->setMargin(4);        //边距调整
 
    //初始化布局
    vLayout = new QVBoxLayout();  //承载文字
    vLayout->addWidget(label);
    vLayout->setAlignment(Qt::AlignCenter);
 
    hLayout = new QHBoxLayout();  //承载图标和vLayout
    //hLayout->addWidget(labIcon);  预留显示图标
    hLayout->addLayout(vLayout);
    hLayout->setAlignment(Qt::AlignCenter);
    this->setLayout(hLayout);
 
    //初始化定时器
    connect(&durationTimer, &QTimer::timeout, this, &SToast::timeOver);
}
 
SToast::~SToast()
{
    delete label; label = NULL;
    delete labIcon; labIcon = NULL;
    delete vLayout; vLayout = NULL;
    delete hLayout; hLayout = NULL;
}
 
int SToast::duration() const
{
    return msDuration;
}
 
void SToast::SetDuration(int msec)
{
    msDuration = msec;
}
 
void SToast::setMessageVDuration(QString msg, int msecDisplayTime/*=2500*/)
{
    // 待完善的功能
    // 1. 对消息进行排队显示,忽略用户指定的显示时间,采用默认的显示时间
    // 2. 对msg的长度适当限制
 
    this->show();
 
    if(!msg.isEmpty()){
        label->setText(msg);
    }
    else{
        label->setText("");
    }
    msDuration = msecDisplayTime;
 
    //淡出画效果
    fadeOutAnimation();
 
    //开始显示计时
    durationTimer.start(msDuration);
}
 
void SToast::fadeInAnimation()
{
    //界面动画,改变透明度的方式消失1 - 0渐变
    if(!animation)
        return;
    connect(animation, &QPropertyAnimation::finished, this, &SToast::fadeInAnimationFinished );
 
    animation->setDuration(1500);
    animation->setStartValue(0.8);
    animation->setEndValue(0);
    //animation->setEasingCurve(QEasingCurve::OutBounce);
    animation->start();
}
 
void SToast::fadeOutAnimation()
{
    //界面动画,改变透明度的方式出现0 - 1渐变
    if(!animation)
        return;
    animation->setDuration(1500);
    animation->setStartValue(0);
    animation->setEndValue(0.8);
    animation->start();
}
 
void SToast::timeOver()
{
    durationTimer.stop();
 
    //测试
    //label->setText("显示时间到,你还有什么想说的吗?");
 
    //淡入动画效果
    fadeInAnimation();
}
 
void SToast::fadeInAnimationFinished()
{
    disconnect(animation, &QPropertyAnimation::finished, this, &SToast::fadeInAnimationFinished );
    this->close();
}
 
void SToast::paintEvent(QPaintEvent *event)
{
    //TODO: coding below
 
 
    QWidget::paintEvent(event);
}

其中有些参数是设置固定的,可根据个人需求进行更改,比如,toast显示位置横向在屏幕中间,纵向在屏幕7/8的 位置。。。

接下来就是调用了,在调用函数中首先 要包含其类的头文件,然后调用代码如下

SingleTonSToast::getInstance().setMessageVDuration("自定义类模拟toast测试toast", 2200);

函数的第一个参数是想toast的内容,第二个参数是toast显示的时间2200ms,第一种方法介绍完毕,如果只是简单的应用,不用麻烦的去创建java文件,用此方法即可调用,尤其是可在桌面应用程序中效果更为显著,在Android应用中建议用第二种方式。

3.2 调用Android原生的toast方法

此种方法只限应用在Android上,在window上无法实现,如果未配置过java的继承类,要配置一下,对于新手来说也算是复杂了,下面详细介绍无到有的步骤。

首先打开一个未配置过的项目,可以看到other files内无AndroidManifest.xml和java文件,没有other files文件夹的朋友也不要慌,不用自己创建,我这个就当 是没有一样一会添加文件会自动有
在这里插入图片描述
放一个我的配置图
在这里插入图片描述
编译一下你的qt for Android程序,可以发现在工程目录下

有个android-build文件夹,其中有个AndroidManifest.xml文件是我们需要的。

在工程目录下新建一个文件夹叫aaa,把xml文件放进去,如下
在这里插入图片描述
在你的pro文件中添加以下代码,意思是生成apk时会调用aaa文件夹中的AndroidManifest.xml文件

ANDROID_PACKAGE_SOURCE_DIR = $$PWD/aaa

右键你的工程,添加现有文件,选择aaa中的xml文件,就有了以下内容
在这里插入图片描述
可以看到AndroidManifest.xml添加进来了,双击xml可配置Android的一些内容,比如图标啊,程序名称啊,也可进入xml程序中配置
在这里插入图片描述
可以切换xml程序和此界面。
在这里插入图片描述
到此,步骤完成1/3,以后发帖再也不会介绍这个的创建了,因为这是qt for Android最基础的东西了,也是开启qt开发Android的第一步和大门,反反复复介绍也没有必要。

接下里到了qt调用Android原生资源的关键步骤。

在aaa文件夹下的src文件夹下创建一个com文件夹
在这里插入图片描述
返回程序,创建新文件在这里插入图片描述
命名随意,看个人,路径选择刚建立的com文件夹下在这里插入图片描述
建立完毕,弹出如下界面,现在界面是空的,没有任何程序,程序运行起来也不会执行到这里,要配置一下,才可以执行这里进而去调用Android原生的一些资源,开启了qt for Android的大门,是从这里进去的。
在这里插入图片描述
java文件中添加如下代码

package com.ZtActivity;
import android.content.Intent;
import android.widget.Toast;
import android.os.Handler;
import android.os.Message;
import org.qtproject.qt5.android.bindings.QtActivity;
public class ZtActivity extends org.qtproject.qt5.android.bindings.QtActivity{
 
    private static ZtActivity m_instance;
    private static Handler m_handler = new Handler() {
         @Override
         public void handleMessage(Message msg) {
             switch (msg.what) {
             case 1:
                 Toast toast = Toast.makeText(m_instance,(String)msg.obj, Toast.LENGTH_SHORT);
                 toast.show();
                 break;
             };
         }
     };
     public ZtActivity(){
             m_instance = this;
         }
     public static void makeToast(String s){
         m_handler.sendMessage(m_handler.obtainMessage(1, s));
     }
 
}

第一行的package是很重要的

接下来打开xml文件,选择代码模式,找到划横线的行
在这里插入图片描述
后面有句Android:name
在这里插入图片描述
将其修改为
在这里插入图片描述
配置基本完毕,接下来去配置调用的方式,在pro文件中添加红框中内容,是要调用Android的资源
在这里插入图片描述
然后在你想调用toast的函数加上头文件

void Home::closeEvent(QCloseEvent *event)//点击系统自带关闭按钮回调函数
{
    QAndroidJniObject javaToast = QAndroidJniObject::fromString("原生Android测试toast");
        QAndroidJniObject::callStaticMethod<void>("com/ZtActivity/ZtActivity",
                                           "makeToast",
                                           "(Ljava/lang/String;)V",
                                           javaToast.object<jstring>());
 
   // event->ignore();//失能关闭窗口功能,只能隐藏/显示
}

编译,到手机,很顺利的部署成功。

参考链接
Qt for Android调用android原生Toast控件
https://www.2cto.com/kf/201702/603177.html

Qt for Android创建AndroidManifest.xml和Java类文件https://blog.csdn.net/luoyayun361/article/details/72993841

关于使用toast这篇文章讲的很清楚,确实学到了,怕忘记、找不到等特此粘贴过来,非常感谢原文博主!

原文链接:qt for Android使用原生方式和自建类方式实现toast效果

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐