Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
ML(Qt Modeling Language)是一種用于描述用戶界面的聲明性語言,它是Qt框架中用于創建現代、動態用戶界面的一種重要方式。QML提供了豐富的功能,包括但不限于以下幾個方面:
總之,QML作為Qt框架中重要的一部分,提供了豐富的功能和靈活的特性,使得開發者能夠快速構建現代化的用戶界面,并可以輕松實現豐富的交互效果和動畫效果。
間因素
開發程序時,必須盡可能實現一致的60幀/秒刷新率。60幀/秒意味著每幀之間大約有16毫秒可以進行處理,其中包括將繪圖基元上傳到圖形硬件所需的處理。
那么,就需要注意以下幾個重要的點:
1.盡可能使用異步,事件驅動編程
2.使用工作線程進行重要處理
3.永遠不要手動控制事件循環
4.在阻塞函數中,每幀的花費不要超過幾毫秒
如果不這樣做,那么將會發生調整,影響用戶體驗。
注意:永遠不應該使用的模式是創建自己的QEventLoop或調用QCoreApplication :: processEvents(),以避免在從QML調用的C ++代碼塊中阻塞。這樣做非常危險,因為當在信號處理程序或綁定中輸入事件循環時,QML引擎繼續運行其他綁定,動畫,轉換等。然后這些綁定會導致副作用,例如,破壞包含整體層次結構事件循環。
剖析
最重要的提示是:使用Qt Creator附帶的QML分析器。了解應用程序在何處花費時間將使您能夠專注于實際存在的問題區域,而不是可能存在的問題區域。有關如何使用QML分析工具的更多信息,請參閱Qt creator 幫助文檔。
如果不進行分析而直接去優化代碼,可能效果并不會很明顯,借助分析器將會更快的定位到消耗性能的模塊,然后再進行重新設計,以便提高性能。
JavaScript代碼
大多數QML應用程序將以動態函數、信號處理程序和屬性綁定表達式的形式包含大量JavaScript代碼。這通常不是問題,由于QML引擎中的一些優化,例如對綁定編譯器所做的那些優化,它可以(在某些用例中)比調用C ++函數更快。但是,必須注意確保不會意外觸發不必要的處理。
綁定
QML中有兩種類型的綁定:優化綁定和非優化綁定。保持綁定表達式盡可能簡單是一個好主意,因為QML引擎使用優化的綁定表達式求值程序,它可以評估簡單的綁定表達式,而無需切換到完整的JavaScript執行環境。與更復雜(非優化)的綁定相比,這些優化的綁定的評估效率更高。優化綁定的基本要求是在編譯時必須知道所訪問的每個符號的類型信息。
綁定表達式時要避免的事情,以達到最大的優化:
1.聲明中間JavaScript變量
2.訪問“var”屬性
3.調用JavaScript函數
4.構造閉包或在綁定表達式中定義函數
5.訪問直接評估范圍之外的屬性
6.寫作其他屬性作為副作用
立即評估范圍可以概括為它包含:
1.表達式范圍對象的屬性(對于綁定表達式,這是屬性綁定所屬的對象)
2.組件中任何對象的ID
3.組件中根項的屬性
來自其他組件的對象和任何此類對象的屬性,以及JavaScript導入中定義或包含的符號都不在直接評估范圍內,因此不會優化訪問任何這些對象的綁定。
類型轉換
使用JavaScript的一個主要成本是,在大多數情況下,當訪問QML類型的屬性時,會創建一個包含底層C ++數據(或對它的引用)的外部資源的JavaScript對象。在大多數情況下,這是不會太影響性能,但在其他情況下,它可能相當消耗性能。比如是將C ++ QVariantMap Q_PROPERTY分配給QML“variant”屬性。列表也可能是有損性能的,盡管(特定類型的序列的QList為int, qreal,布bool,QString,和QUrl)應該相對來說不會太影響, 其他列表類型可能會帶來昂貴的轉換成本(創建新的JavaScript數組,逐個添加新類型,從C ++類型實例到JavaScript值的每類型轉換)。
在一些基本屬性類型(例如“string”和“url”屬性)之間轉換也可能很影響性能。使用最接近的匹配屬性類型將避免不必要的轉換。
如果必須將QVariantMap公開給QML,請使用“var”屬性而不是“variant”屬性。一般來說,對于來自QtQuick 2.0及更新版本的每個用例,“property var”應該被認為優于“property variant” (注意“property variant”被標記為過時),因為它允許真正的JavaScript引用存儲(可以減少某些表達式中所需的轉換次數)。
解決屬性
雖然在某些情況下可以緩存和重用查找結果,但如果可能的話,最好完全避免完成不必要的工作。
在下面的示例中,我們有一個經常運行的代碼塊(在這種情況下,它是顯式循環的內容;但它可能是一個通常評估的綁定表達式,例如),在其中,我們解決了具有“rect”id及其“color”屬性的對象多次調用:
// bad.qml
import QtQuick 2.3
Item {
width: 400
height: 200
Rectangle {
id: rect
anchors.fill: parent
color: "blue"
}
function printValue(which, value) {
console.log(which + "=" + value);
}
Component.onCompleted: {
var t0=new Date();
for (var i=0; i < 1000; ++i) {
printValue("red", rect.color.r);
printValue("green", rect.color.g);
printValue("blue", rect.color.b);
printValue("alpha", rect.color.a);
}
var t1=new Date();
console.log("Took: " + (t1.valueOf() - t0.valueOf()) + " milliseconds for 1000 iterations");
}
}
我們可以在塊中只解析一次公共基數:
// good.qml
import QtQuick 2.3
Item {
width: 400
height: 200
Rectangle {
id: rect
anchors.fill: parent
color: "blue"
}
function printValue(which, value) {
console.log(which + "=" + value);
}
Component.onCompleted: {
var t0=new Date();
for (var i=0; i < 1000; ++i) {
var rectColor=rect.color; // resolve the common base.
printValue("red", rectColor.r);
printValue("green", rectColor.g);
printValue("blue", rectColor.b);
printValue("alpha", rectColor.a);
}
var t1=new Date();
console.log("Took: " + (t1.valueOf() - t0.valueOf()) + " milliseconds for 1000 iterations");
}
}
只需這一簡單的改變就可以顯著提高性能。請注意,上面的代碼可以進一步改進(因為在循環處理期間查找的屬性永遠不會改變),通過將屬性解析提升出循環,如下所示:
// better.qml
import QtQuick 2.3
Item {
width: 400
height: 200
Rectangle {
id: rect
anchors.fill: parent
color: "blue"
}
function printValue(which, value) {
console.log(which + "=" + value);
}
Component.onCompleted: {
var t0=new Date();
var rectColor=rect.color; // resolve the common base outside the tight loop.
for (var i=0; i < 1000; ++i) {
printValue("red", rectColor.r);
printValue("green", rectColor.g);
printValue("blue", rectColor.b);
printValue("alpha", rectColor.a);
}
var t1=new Date();
console.log("Took: " + (t1.valueOf() - t0.valueOf()) + " milliseconds for 1000 iterations");
}
}
屬性綁定
如果更改了引用的任何屬性,則將重新評估屬性綁定表達式。因此,綁定表達式應盡可能簡單。
如果你有一個循環來進行某些處理,但只有處理的最終結果很重要,通常最好更新一個臨時累加器,然后將其分配給需要更新的屬性,而不是逐步更新屬性本身,以避免在累積的中間階段觸發重新評估結合表達。
以下的例子說明了這一點:
// bad.qml
import QtQuick 2.3
Item {
id: root
width: 200
height: 200
property int accumulatedValue: 0
Text {
anchors.fill: parent
text: root.accumulatedValue.toString()
onTextChanged: console.log("text binding re-evaluated")
}
Component.onCompleted: {
var someData=[ 1, 2, 3, 4, 5, 20 ];
for (var i=0; i < someData.length; ++i) {
accumulatedValue=accumulatedValue + someData[i];
}
}
}
onCompleted處理程序中的循環導致“text”屬性綁定被重新評估六次(然后導致依賴于文本值的任何其他屬性綁定,以及onTextChanged信號處理程序,每次重新評估時間,并列出每次顯示的文本)。在這種情況下,這顯然是不必要的,因為我們只關心最終的值。
那么,以上代碼可以改成這樣:
// good.qml
import QtQuick 2.3
Item {
id: root
width: 200
height: 200
property int accumulatedValue: 0
Text {
anchors.fill: parent
text: root.accumulatedValue.toString()
onTextChanged: console.log("text binding re-evaluated")
}
Component.onCompleted: {
var someData=[ 1, 2, 3, 4, 5, 20 ];
var temp=accumulatedValue;
for (var i=0; i < someData.length; ++i) {
temp=temp + someData[i];
}
accumulatedValue=temp;
}
}
序列提示
如前所述,某些序列類型很快(例如,QList ,QList ,QList ,QList < QString >,QStringList和QList < QUrl >),而其他序列類型則要慢得多。除了盡可能使用這些類型而不是較慢類型之外,還需要注意一些其他與性能相關的語法以獲得最佳性能。
首先,對于序列類型的兩種不同的實現:一個是當序列是Q_PROPERTY一個的QObject的(我們稱此為參考序列),另一個用于在序列從返回Q_INVOKABLE一個功能的QObject(我們將這稱為復制序列)。
通過QMetaObject :: property()讀取和寫入引用序列,因此讀取和寫入QVariant。這意味著從JavaScript更改序列中任何元素的值將導致三個步驟發生:將從QObject讀取完整序列(作為QVariant,但隨后轉換為正確類型的序列); 指定索引處的元素將在該序列中更改; 并且完整的序列將被寫回QObject(作為QVariant)。
復制序列更簡單,因為實際序列存儲在JavaScript對象的資源數據中,因此不會發生讀取/修改/寫入循環(而是直接修改資源數據)。
因此,對參考序列的元素的寫入將比寫入復制序列的元素慢得多。實際上,寫入N元素參考序列的單個元素與將N元素復制序列分配給該參考序列的成本相當大,因此通常最好修改臨時復制序列,然后將結果分配給計算過程中的參考序列。
假設以下C ++類型存在,并且已經正常注冊過:
class SequenceTypeExample : public QQuickItem
{
Q_OBJECT
Q_PROPERTY (QList<qreal> qrealListProperty READ qrealListProperty WRITE setQrealListProperty NOTIFY qrealListPropertyChanged)
public:
SequenceTypeExample() : QQuickItem() { m_list << 1.1 << 2.2 << 3.3; }
~SequenceTypeExample() {}
QList<qreal> qrealListProperty() const { return m_list; }
void setQrealListProperty(const QList<qreal> &list) { m_list=list; emit qrealListPropertyChanged(); }
signals:
void qrealListPropertyChanged();
private:
QList<qreal> m_list;
};
以下示例在多次循環中寫入引用序列的元素,從而導致性能下降:
// bad.qml
import QtQuick 2.3
import Qt.example 1.0
SequenceTypeExample {
id: root
width: 200
height: 200
Component.onCompleted: {
var t0=new Date();
qrealListProperty.length=100;
for (var i=0; i < 500; ++i) {
for (var j=0; j < 100; ++j) {
qrealListProperty[j]=j;
}
}
var t1=new Date();
console.log("elapsed: " + (t1.valueOf() - t0.valueOf()) + " milliseconds");
}
}
由表達式引起的內部循環中的QObject屬性讀取和寫入"qrealListProperty[j]=j"使得此代碼非常不理想。相反,更好的一種方法是:
// good.qml
import QtQuick 2.3
import Qt.example 1.0
SequenceTypeExample {
id: root
width: 200
height: 200
Component.onCompleted: {
var t0=new Date();
var someData=[1.1, 2.2, 3.3]
someData.length=100;
for (var i=0; i < 500; ++i) {
for (var j=0; j < 100; ++j) {
someData[j]=j;
}
qrealListProperty=someData;
}
var t1=new Date();
console.log("elapsed: " + (t1.valueOf() - t0.valueOf()) + " milliseconds");
}
}
其次,如果屬性中的任何元素發生變化,則會發出屬性的更改信號。如果你對序列屬性中的特定元素有很多綁定,最好創建一個綁定到該元素的動態屬性,并將該動態屬性用作綁定表達式中的符號而不是sequence元素,因為它將只有在其值發生變化時才會重新評估綁定。
// bad.qml
import QtQuick 2.3
import Qt.example 1.0
SequenceTypeExample {
id: root
property int firstBinding: qrealListProperty[1] + 10;
property int secondBinding: qrealListProperty[1] + 20;
property int thirdBinding: qrealListProperty[1] + 30;
Component.onCompleted: {
var t0=new Date();
for (var i=0; i < 1000; ++i) {
qrealListProperty[2]=i;
}
var t1=new Date();
console.log("elapsed: " + (t1.valueOf() - t0.valueOf()) + " milliseconds");
}
}
請注意,即使在循環中僅修改索引2處的元素,也會重新評估三個綁定,因為更改信號的粒度是整個屬性已更改。因此,添加中間綁定有時可能是有益的:
// good.qml
import QtQuick 2.3
import Qt.example 1.0
SequenceTypeExample {
id: root
property int intermediateBinding: qrealListProperty[1]
property int firstBinding: intermediateBinding + 10;
property int secondBinding: intermediateBinding + 20;
property int thirdBinding: intermediateBinding + 30;
Component.onCompleted: {
var t0=new Date();
for (var i=0; i < 1000; ++i) {
qrealListProperty[2]=i;
}
var t1=new Date();
console.log("elapsed: " + (t1.valueOf() - t0.valueOf()) + " milliseconds");
}
}
在上面的示例中,每次僅重新評估中間綁定,從而導致顯著的性能提升。
值類型提示
值類型屬性(font,color,vector3d等)具有類似的QObject屬性,并將通知語義更改為序列類型屬性。因此,上面給出的序列提示也適用于值類型屬性。雖然它們通常不是值類型的問題(因為值類型的子屬性的數量通常遠小于序列中元素的數量),所以重新評估的綁定數量的任何增加不必要地會對績效產生負面影響。
其他JavaScript對象
不同的JavaScript引擎提供不同的優化。Qt Quick 2使用的JavaScript引擎針對對象實例化和屬性查找進行了優化,但它提供的優化依賴于某些標準。如果你的應用程序不符合標準,則JavaScript引擎會回退到“慢速路徑”模式,性能會更差。因此,請始終盡量確保您符合以下條件:
1.盡可能避免使用eval()
2.不要刪除對象的屬性
【領QT開發教程學習資料,點擊下方鏈接莬費領取↓↓,先碼住不迷路~】
點擊這里:「鏈接」
t Quick 為 Qt 引入了一門叫 QML(Qt Meta/Modeling Language)的腳本語言,它是 ECMAScript 標準的實現。所以 QML 語法是在 ECMAScript 語法的基礎上實現的。
ECMAScript 語言的標準是由 Netscape、Sun、微軟、Borland 等公司基于 JavaScript 和 JScript 錘煉、定義出來的。
ECMAScript 僅僅是一個描述,定義了腳本語言的所有屬性、方法和對象。其他語言可以實現 ECMAScript 來作為功能的基礎,正如 JavaScript 那樣。這個實現又可以被擴展,包含特定于宿主環境的新特性,比如 QML 就引入了 Qt 對象系統中的信號與槽,還增加了動態屬性綁定等非常有特色的新功能。
作為一種全新的編程語言,QML 有三個核心:
下面一個個來看 ECMAScript 的語法。(QML 是 ECMAScript 標準的實現,所以兩者語法是基本一樣的)
1. 1、區分大小寫
與 C++ —樣,變量、函數名、運算符以及其他一切東西都是區分大小寫的,也就是說, 變量 area 和 Area 是不同的。
1.2、弱類型
與 C++ 不同,ECMAScript 中的變量沒有特定的類型,定義變量時只用 var 運算符,可以將它初始化為任意的值,你可以隨時改變變量所存儲的數據類型(實際上應當盡量避免這樣做)。例如:
var i=0
console.log(i)
i="hello"
console.log(i)
盡管在語法上這么做沒有問題,但好的編碼習慣是一個變量始終存放相同類型的值。
1.3. 語句后的分號可有可無
C、C++、Java 等語言都要求每條語句以分號(;)結束。ECMAScript 則允許開發者自行決定是否以分號結束一行代碼。如果沒有分號,ECMAScript 就把這行代碼的結尾看作該語句的結束(與 Lua、Python、Visual Basic 相似)。至于加不加分號,那就看自己的喜好了。下面兩行代碼的語法都是正確的:
var background="white"
var i=0
在 ECMAScript 中使用 var 運算符聲明變量,與 C++ 類似,變量名需要遵循一定的規則。
2.1、變量聲明
變量用 var 運算符加變量名來定義。例如:
var i=0
在這個例子中,聲明了變量 i 并把它初始化為 0。你也可以不初始化,在用到時再初始化。
一個 var 語句可以定義多個變量。例如:
var i=0 , name="j"
這個例子定義了變量 i,初始化為數字;還定義了變量 name,初始化為字符串。你看到了,這和 C++ 或 Java 不同,一個 var 語句定義的多個變量可以有不同的類型。
2.2、變量命名規則
變量命名需要遵守兩條簡單的規則:
下面這些變量名都是合法的:
var test
var objectName
var —phone
var $1
為了代碼的可讀性,在命名變量時還應該遵循一定的命名風格。因為 Qt 是基于 C++ 的應用框架,QML 又是 Qt 框架的一部分,這里建議和 Qt C++ 代碼采取同樣的命名風格—駝峰命名法。
對于變量(包括函數名),以小寫字母開始,單詞之間采用駝峰命名法。對于類名,以大寫字母開始,單詞之間采用駝峰命名法。
QT開發交流+貲料君羊:714620761
ECMAScript 有 5 種原始類型,即 Undefined、Null、Boolean、Number 和 String。每種原始類型定義了它包含的值的范圍及其字面量表示形式。
ECMAScript 提供了 typeof 運算符來判斷一個值的類型,如果這個值是原始類型,typeof 還會返回它具體的類型名字;而如果這個值是引用值,那么 typeof 統一返回 ”object” 作為類型名字。示例如下:
import QtQuick 2.2
Rectangle {
Component.onCompleted:{
var name="Zhang San Feng"
console.log(typeof name) // 輸出:qml:string
console.log(typeof 60) // 輸出:qml:number
}
}
變量 name 的類型是 string,字面量 60 的類型是 number。其中 “qml:” 是使用 console.log 輸出信息時攜帶的前綴。
3.1、Undefined 類型
Undefined 類型只有一個值,即 undefined。當聲明的變量未初始化時,該變量的默認值就是 undefined。例如:
var temp
上面的代碼聲明了變量 temp 但并未顯式地講行初始化,它的值將被設置為 undefined, 這和 C++ 不同。ECMAScript 的這一特性:未初始化的變量也有固定的初始值,我們可以將一個變量和 undefined 比較來實現一些業務邏輯。比如:
var runOnce;
...
if(runOnce==undefined) {
runOnce=true
}
else {
...
}
當函數沒有明確的返回值時,返回的值也是 undefined,如下所示:
function blankFunc(){}
console.log(blankFunc()==undefined) // 輸出:true
3.2、Null 類型
Null 類型也只有一個值,即 null。
你可以顯式地將一個變量初始化為 null,然后據此實現一些邏輯。
3.3、Boolean 類型
Boolean 是 ECMAScript 中最常用的類型之一,它有 true 和 false 兩個值。
3.4、Number 類型
Number 類型是最特殊的,它既可以表示 32 位的整數,也可以表示 64 位的浮點數。你在 QML 代碼中直接輸入的任何數字都被看作是 Number 類型的字面量。
下面的代碼聲明了存放整數值的變量:
var integer=10
數字類型的最大值是 Number.MAX_VALUE,最小值是 Number.MlN_VALUE,它們定義了 Number 值的外邊界,所有的 ECMAScript 數都必須在這兩個值之間。
3.5、String 類型
ECMAScript 中的 String 類型是作為原始類型存在的,它存儲 Unicode 字符,對應的 Qt C++ 類型為 QString。當你混合 C++ 和 QML 編程時,所有的 QString 類型的變量都會被映射為 ECMAScript 中的 String。
字符串字面量可以用雙引號(")或單引號(')來聲明。而在 Qt 中,只能用雙引號, 單引號表示字符。為了一致性,建議你盡可能不要使用單引號表示字符串。在 ECMAScript 中沒有字符類型,這也是為什么你可以使用單引號來表示字符串的原因。下面的兩行代碼都是有效的:
var name='Lv Bu'
var name="Guan Yu"
如果一種編程語言不支持類型轉換,那真是無法想象。在 ECMAScript 中,類型轉換非常簡單。
4.1、轉換成字符串
Boolean、Number、String 三種原始類型,都有 toString() 方法,可以把它們的值轉換為字符串。比如下面的代碼在 Qt 中可以正常運行:
var name="Zhang San Feng"
console.log(name.toString())
console.log(true.toString())
var visible=false
console.log(visible.toString())
var integer=3.14159
console.log(integer.toString())
Number 類型的 toString() 方法還可以按基轉換,比如:
var integer=13
console.log (integer.toString(16)) // 輸出: D
如果你不指定數基,那不管原來是用什么形式聲明的 Number 類型,toString() 都按十進制輸出。
4.2、轉換成數字
parselnt() 和 parseFloat() 可以把非數字的原始值轉換成數字,前者把值轉換為整數,后者把值轉換成浮點數。這兩個方法只能用于 String 類型,如果你對其他類型調用它們, 返回值將是奇葩的 NaN。
parselnt() 和 parseFloat() 會掃描字符串,直到遇到第一個非數字字符時停止,將轉換的結果返回。比如parselnt(”2014年")將會返回 2014。對于 parseFloat(),會將第一個小數點作為有效字符,而 parselnt() 則不會。
下面是一些示例:
var numl=parselnt ("2014 年") // 輸出:2014
var num2=parselnt ("OxC") // 輸出:12
var num3=parselnt ("3.14") // 輸出:3
var num4=parselnt ("green") // 輸出:NaN_
var num5=parseFloat ("3.14159") // 輸出:3.14159
var num7=parseFloat ("Am I Float") // 輸出:NaN
parselnt() 還支持基模式,下面是一些示例:
var numl=parselnt ("AK47", 16) // 輸出:10
var num2=parselnt ("AK47", 10) // 輸出:NaN
var num3=parselnt ("010", 8) // 輸出:8
var nun4=parselnt ("010", 10) // 輸出:10
需要注意的是,代表浮點數的字符串必須以十進制形式表示,比如parseFloat(“OxFE”),返回 NaN。
4.3、強制類型轉換
如果你是 C/C++ 程序員,對強制類型轉換一定又愛又恨。ECMAScript 也支持強制類型 轉換,有三種轉換:
ECMAScript 中的函數,就是具名的、可重復使用的代碼塊。另外,ECMAScript 不支持函數重載。
5.1、函數語法
函數語法如下:
function functionName(arg1, arg2, ..., argN){
// 要執行的代碼
}
function 是定義函數時必須使用的關鍵字。functionName可以任意取,符合變量命名規則即可。 arg1 到 argN 是函數的參數,當然也可以沒有參數。花括號內是要執行的代碼塊。
無參函數示例:
function quitApp(){
Qt .quit ();
}
帶參函數示例:
function showError(msg){
console.log("error - ", msg);
}
function travel(country, city){
console.log("Welcome to ", city, " , ", country);
}
當我們使用函數參數的時候,參數就像不帶 var 運算符的變量聲明一樣。這與 C++ 中必須給函數參數指明類型大相徑庭。
5.2、函數的返回值
ECMAScript 中的函數,默認都是有返回值的,即便你沒有顯式使用 return 語句,它也會返回 undefined。如果你想把函數運算的結果返回給調用它的地方,可以使用 return 語句。下面是個簡單的示例:
function add(numberl, number2){
var result=number1 + number2;
console.log(number1, "+" ,number2, result);
return result;
}
QT開發交流+貲料君羊:714620761
你可以這樣調用 add() 函數:var ret=add(100, 34);。
ECMAScript 的運算符和 C++、Java 等語言的差不多,具體內容不再贅述。這里只重點介紹一下關鍵字運算符。void、typeof、instanceof、new、delete 這些都是關鍵字運算符。
console 提供了輸出日志信息、斷言、計時器、計數器、性能分析等功能,這里只介紹前三個我們經常用到的功能。
7.1、輸出日志信息
console對象提供了多個打印調試信息的方法:
7.2、斷言
console.assert() 提供斷言功能,它接受一個表達式,當表達式的值為 false 時會輸出調試信息,打印 QML 所在行。例如:console.assert (false)。
如果你傳遞了額外的參數給 console.assert(),它會在控制臺輸出這些信息。示例:
var years=0;
for (; years < 18; years++){
console.log("I\'m minor");
continue;
console.log ("You shoult not see me"};
}
console.assert(years < 18, years);
上面的斷言語句,將會輸出下列信息:
18
onCompleted (file:///F:/projects/qtquick/qmls/show_type.qml:187)
需要注意的是,在 QML 中,使用 console.assert(),斷言失敗,程序并不會終止運行。
7.3、計時器
console 提供了計時器功能,方便我們測量某些代碼的耗時情況。
console.time(tag) 啟動定時器,字符串類型的 tag 是必需的。console.timeEnd(tag) 停止計時器,在控制臺輸出某個標簽對應的耗時信息。tag 是必需的。 下面是簡單的示例:
*請認真填寫需求信息,我們會在24小時內與您取得聯系。