QT、QML、C++中常用功能整理(持续更新...)

一、环境相关(.pro文件)

● Qt Creator中最最常用快捷键

F1        			查看帮助(可直接在某个控件上)
F2        			跳转到函数定义(和Ctrl+鼠标左键一样的效果)
F4       	 		头文件和源文件之间切换
Ctrl + B        	编译工程
Ctrl + R        	运行工程
Ctrl + I        	自动对齐
Ctrl + /        	注释行,取消注释行
Ctrl + Shift + <    折叠代码块
Ctrl + Shift + >    展开代码块
Alt + 0    			关闭/打开左侧显示(方便编辑)

● 多线程编译

在这里插入图片描述
-j16 是开启16线程编译,主要得看自己的电脑核心数,稳妥一点 -j4 一般电脑都OK的。

据我测试,加不加编译时间都一样,应该新版本的QtCreator默认已经会根据电脑的核心自动设置多线程编译,比如识别到你的电脑是16核心的就会默认设置-j16参数进行编译

● Windows下中文乱码问题

在 .pro文件中加入如下:

WindowsBuild {
	QMAKE_CXXFLAGS += -execution-charset:utf-8  # 让程序执行时使用utf-8字符集
	QMAKE_CXXFLAGS += -source-charset:utf-8     # 告诉vc编译器识别源文件编码类型是utf-8
}

或者:

WindowsBuild {
	msvc {
	    QMAKE_CFLAGS += /utf-8
	    QMAKE_CXXFLAGS += /utf-8
	}
}

重构后再编译才生效,实测有效~

● .pro 工程文件中添加常用模块

相应的功能必须添加指定的模块才能运行,如使用网络的话,必须在 .pro 中添加: QT += network

QT += \
 	sql \			  # 数据库
    svg \             # svg 图(亲测,不包含的话,手机app中将不显示svg 图)
    network \         # tcp/UDP 网络
    websockets \      # web 网络
    xml \             # xml 文件
    concurrent \      # 多线程
    gui \             # Graphical User Interface (图形用户界面)
    location \        # 地图定位相关
    opengl \          # 三维绘图
    positioning \     # 通过 QML 和 c++ 接口提供定位信息。 
    qml \             # 提供了使用 QML 语言创建用户界面所需的 QML 类型 
    quick \           # 高级用户界面技术, 默认使用 OpenGL ES, 包含 QML APIC++ API 
    quickcontrols2 \  # Qt 自带 controls 控件库,一般是几个基础控件组成的复杂控件
    widgets \         # 传统桌面程序 widgets,对应于 QML
    quickwidgets \    # 
    texttospeech \
    core-private      
    ...

● 关闭大量警告

.pro 工程文件添加:

CONFIG += warn_off

● 关闭qDebug、qWarning打印

.pro 工程文件添加:

DEFINES += QT_NO_DEBUG_OUTPUT
DEFINES += QT_NO_WARNING_OUTPUT #会编译失败....

● .pro文件中,使用$$quote(xxx),对带空格的路径进行包围

一个错误的例子如下:

INCLUDEPATH += C:/Program Files/GmSSL/include
LIBS += -LC:/Program Files/GmSSL/lib -llibcrypto

编译时,找不到头文件,因为路径C:/Program Files中带了空格,所以需要处理下,如下:

INCLUDEPATH += $$quote(C:/Program Files/GmSSL/include)
LIBS += -L$$quote(C:/Program Files/GmSSL/lib) -llibcrypto

二、小技巧

  • 属性改变事件,基本都是 on+Property+Changed
  • findChild 使用里面的参数,对应的是QML中的objectName,不是QML中的id
  • QML对象,如果没有设置id,则使用时才初始化,如果设置了id,则一开始就初始化了,所以不要给id最好
  • QML子对象可以直接使用父对象的属性,跨文件的情况同样可用
  • QML定义的function可以全局使用,子对象能使用父对象的函数,父对象不能直接使用
  • 不能修改JS变量给其他文件使用,每次import相对于基于js创建一个新的对象
  • 可以使用Qt.binding,进行属性值的绑定
  • ① QQuickView 提供了一个窗体用于显示UI
    ② QQuickEngine 提供QML运行环境
    ③ QQuickWindow 显示窗体, 以及对item对象的管理及用户交互

三、QML 中数据处理(函数相关)

 
可参考: QML 中常用的 JS 函数整理

● 子项的批量操作

利用 childrenstartsWith,如下,clearAllChecks() 函数可以批量操作 RowLayoutMyButton ,可以跳过 ColoredImage

function clearAllChecks() {
    for (var i=0; i<rowLayout.children.length; i++) {
       if (rowLayout.children[i].toString().startsWith("MyButton"))
            rowLayout.children[i].checked = false
        }
}

RowLayout {
     id:                     rowLayout
     ...
     //head
     ColoredImage {
         id:                 innerImage
         ...
     }
     //first Button
     MyButton {
         id:                 firstButton
         text:               qsTr("我是目录1")
         icon.source:        "/images/1"
         onClicked: {
             clearAllChecks()
             checked = true
         }
     }
     //second Button
     MyButton {
         text:               qsTr("我是目录2")
         icon.source:        "/images/2"
         onClicked: {
             clearAllChecks()
             checked = true
         }
     }
 }

● 打印

//QML中打印
console.log("index is: ")
//c++中打印
qDebug() << "No Internet Access";

● 将一个数字转化成16进制字符串形式

function toHex(num){    
    return num<16?  "0x0"+num.toString(16).toUpperCase() : "0x"+num.toString(16).toUpperCase();
}

● 小数点位数

xxx.toFixed(x),如:

property real _pi:    3.1415926
_pi.toFixed(2)  //保留两位小数 3.14

● Math应用

Math.min(x, y)  	//取最小值
Math.max(x, y)  	//取最大值
Math.round(x)		//返回一个数字四舍五入后接近的整数

● 数组的使用

var arr1 = [1,2,3];		   // 定义数组 arr = [1,2,3]
var arr2 = new Array;		// 定义数组 arr2 = []

arr2[0] = 4;			// 通过下标添加元素
arr2[1] = 5;
arr2.push(6);			// 往数组最末尾添加新元素
arr2.unshift(7);		// 往数组最前面添加新元素
arr2.unshift(8);

var arr3 = arr1.concat(arr2);	// 合并数组
console.log(arr3);		// [1,2,3,8,7,4,5,6]

console.log(arr3.sort());	// 按ASCII码排序,[1,2,3,4,5,6,7,8]
console.log(arr3.reverse());	// 元素颠倒顺序,[8,7,6,5,4,3,2,1]
console.log(arr3.join("/"));	// 转换成字符串,“8/7/6/5/4/3/2/1”

arr3.pop();			// 数组删除最末尾的元素
arr3.shift();			// 数组删除最前面的元素
console.log(arr3);		// [7,6,5,4,3,2]
console.log(arr3.slice(1,3));	// 截取指定长度的数组,从1到3(不包括3),[6,5]

arr3.splice(1,3);		// 删除指定长度的数组,从1到3(包括3)
console.log(arr3);		// [7,3,2]

● 字符串转数字(Number()、parseInt() )

Number() 将不同的对象值转换为数字:

var x1 = true;
var x2 = false;
var x3 = new Date();
var x4 = "999";
var x5 = "999 888";

Number(x1)  //1
Number(x2)  //0
Number(x3)  //1639300291930,  返回自 UTC 1970 年 1 月 1 日午夜以来的毫秒数
Number(x4)  //999
Number(x5); //NaN

parseInt() 可解析一个字符串,并返回一个整数

parseInt("10")         //10  1 ~ 9 的数字开头,parseInt() 将把它解析为十进制的整数。
parseInt("10.33")      //10
parseInt("34 45 66")   //34  只有字符串中的第一个数字会被返回
parseInt(" 60 ")       //60  开头和结尾的空格是允许的。
parseInt("40 years")   //40
parseInt("He was 40")  //NaN 第一个字符不能被转换为数字,那么返回 NaN。
 
parseInt("0x10")       //16   以 "0x" 开头,解析为十六进制的整数。
parseInt("010")        //10   以"0"为开始时旧的浏览器使用八进制基数。ECMAScript 5,默认的是十进制的基数。
parseInt("10",8)       //8    八进制
parseInt("10",10)      //10   十进制
parseInt("10",16)      //16   十六进制

● 字符串子串 substr代替 substring

如下截图:
在这里插入图片描述
在这里插入图片描述

● 控件截图功能

  Rectangle {
      id: source
      width: 100
      height: 100
      gradient: Gradient {
          GradientStop { position: 0; color: "steelblue" }
          GradientStop { position: 1; color: "black" }
      }
  }
    
    ...
    
 	source.grabToImage(function(result) {
           result.saveToFile("something.png");
           });
	...
	
	//加入时间、Android常用路径
	source.grabToImage(function(result) {
    var nowTime = Qt.formatDateTime(new Date(),"yyyy-MM-dd-HH:mm:ss")
    var path = "/sdcard/Pictures/" + nowTime + ".png"
    result.saveToFile(path);
       });
    }

四、QML

1. QML 地图相关

● 地图中经纬度总结

// 经纬度常用定义:
property var   _coordinate:    QtPositioning.coordinate(0, 0) //先纬度后经度
//定义一个简单Plugin和Map
Plugin {
    id: mapPlugin
    name: "osm" // "mapboxgl", "esri", ...
}
Map {
	id: 			map
    anchors.fill: 	parent
    plugin: 		mapPlugin
    center: 		QtPositioning.coordinate(59.91, 10.75) // Oslo 先纬度后经度
    zoomLevel: 		14
}

//取地图中心经纬高的8位小数    
function mapCenter() {
    var coordinate = map.center
	coordinate.latitude  = coordinate.latitude.toFixed(8)
	coordinate.longitude = coordinate.longitude.toFixed(8)
	coordinate.altitude  = coordinate.altitude.toFixed(8)
	return coordinate
}
//取当前地图中鼠标位置的经纬高
Map {
	id:		map
	...
	MouseArea {
	anchors.fill: parent
	 onClicked: {
		var coordinate = map.toCoordinate(Qt.point(mouse.x, mouse.y), false )
	    coordinate.latitude = coordinate.latitude.toFixed(8)
	    coordinate.longitude = coordinate.longitude.toFixed(8)
	    coordinate.altitude = coordinate.altitude.toFixed(8)  //高一般是无效的
	    }
	}
}

● 地图中取方位角和坐标

azimuthToatDistanceAndAzimuth

property var    changChaCoordinate:    QtPositioning.coordinate(28.2, 113)    //长沙
property var    shangHaiCoordinate:    QtPositioning.coordinate(31.2, 121.5)  //上海
property var 	targetCoordinate:	   QtPositioning.coordinate(0, 0) //目标经纬度,距离长沙100km,在长沙到上海的方向上

//上海相对于长沙的方位角:
var azimuth =  changChaCoordinate.azimuthTo(shangHaiCoordinate)
//计算目标经纬度,给一个距离和方位角,就可以确定另外一个经纬度:
targetCoordinate = changChaCoordinate.atDistanceAndAzimuth(1000000, azimuth)

2. 时间

	property real   _Time:               //时间为int数字
	...
 	function getMissionTime() {
        if(isNaN(_Time)) {
            return "00:00:00"
        }
        var t = new Date(0, 0, 0, 0, 0, Number(_Time))
        return Qt.formatTime(t, 'hh:mm:ss')
    }
	...
    Label {
        text:          getMissionTime()
    }

五、QML 控件

● Row、Column默认宽高

经过测试,Row和Column中可以不指定宽高;

Column 中的默认宽为子控件中最宽的, 默认高为所有子控件高之和加上间隙 ;
另外width = implicitWidth height = implicitHeight;

Row中默认高为子控件中最高的,默认宽为子控件宽之和加上间隙;
另外width = implicitWidth height = implicitHeight;

● ListView 宽高与子控件一致问题

Flickable 控件或者类似与 ListView 继承于Flickable控件的,如果想宽高与子控件一致,可写成:

 ListView {
     width:              contentItem.childrenRect.width
     height:             contentItem.childrenRect.height
     
     model:              xxx
     delegate: 		     xxx
 }

childrenRect 为只读属性,它保存了项目的子元素的集合位置和大小

● Flickable 控件可拖动的关键

Flickable {
        id:                     flickRoot
        clip:                   true
        contentWidth:           content.width               //要比width大
        anchors.fill:           parent
        ...
}

contentWidth 文本宽的大小应该比 width 宽本身要大
clip 裁剪使能,多余的就只能滚动显示

● 控件先确定底层大小

● 其它

Rectangle 中无色:

color:  Qt.rgba(0,0,0,0)

C++未分类

● QT5 增加widgets 模块

在Qt4中,Qt提供的全部图形界面相关类都包含在Qt Gui模块中,但QT5将一些图形界面类移到了QT widgets模块中。所以在Pro文件中,需要增加一句话:

 greaterThan(QT_MAJOR_VERSION, 4):QT += widgets

意思是如果Qt版本大于Qt4,则需要增加 widgets 模块。

● 浮点型判断不报警告

	float f = 0
	void function() {
		if(f == 0.0f )   //数字0改为 0.0f
		...
	}

● unused parameter xxx

未使用的参数xxx告警

Q_UNUSED(xxx);

未完待续…

  • 41
    点赞
  • 62
    收藏
    觉得还不错? 一键收藏
  • 10
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值