最近需要把JSON格式中的一些資料拿出來
看起來像是這樣:
....
"text": "\u4e00\u6bb5\u5149\u5f71,\u4e00\u6bb5\u65c5\u884c\uff0e\n\n #\u4e58\u8457\u5149\u5f71\u53bb\u65c5\u884c\n #travel\n#light",
.....
(前後文就不特別放在這邊了,不重要)
那這種\u4e00\u6bb5... 取下來會是個QByteArray ,先把它們轉成QString
但還是一大串阿! 於是再用QString裡面的split -> QStringlist來承接。
所以現在可以切開變成u4e00,但這還是一個UTF8,所以我們需要再做調整
上網找了很多方法都沒有找到,但是找到了一篇 這裡 於是終於找到方法了!
解決方法其實很簡單:
不管怎麼弄,反正把\u (escape) 這兩個字元弄掉(QString::replace / QString:: remove)
剩下4e00
QString t1 = "4e00";
int Hex = t1.toInt(0, 16);
QString t2 = QChar(Hex);
你會發現t2 就轉成你要的字元了!
如此簡單就解決的困難的問題,就是這樣(我有簡化掉那篇的方法)
End
2016年12月20日 星期二
2015年12月30日 星期三
[Qt] JavaScript / Qt 與Facebook Login SDK 使用
在完成這個專案之前,花了很多時間在research Facebook Login SDK,說實話實在是有點難搞懂
畢竟要透過Qt來使用JavaScript,不是這麼多範例可以參考,所以後來就改變策略-------
在html上寫JS然後透過QWebView+QUrl來呼叫網頁達成目的!
需要知道的
1.JavaScript如何轉址
2.JavaScript的FB login SDK流程如何
3.如何取得response與accessToken(最重要!App通行證)
//
第一個網址:
我們需要自動轉址到Facebook Login畫面
第二個網址:
Login成功以後,需要轉址到第二個網址(如果都轉址到第一個網址,會造成無窮迴圈)
取得accessToken
第三個網址:
為了讓Qt取得accessToken我們必須要在網址上面動手腳,
也就是帶accessToken在網址上,因此第二網址再轉址到第三網址
以上為說明
-----------------------------------------------------------------------------------------------------------------------
1.test1.html
<!DOCTYPE html>
<html>
<head>
<title>Facebook Login</title>
<meta charset="UTF-8">
</head>
<body>
<p>測試文字</p>
<script>
var url2 = 'https://www.facebook.com/dialog/oauth?client_id=你的App ID&scope=email,user_birthday&redirect_uri=第二網址';
setTimeout("location.href=url2",1);//轉址目的地,自動轉址秒數
console.log('test2');
</script>
<div id="status">
</div>
</body>
</html>
2.test2.html
<!DOCTYPE html>
<html>
<head>
<title>Facebook Login JavaScript Example</title>
<meta charset="UTF-8">
</head>
<body>
<p>123</p>
<script>
<!--開頭initial-->
var url;
window.fbAsyncInit = function() {
// init the FB JS SDK
FB.init({
appId : '你的ID',
cookie : true, // enable cookies to allow the server to access
// the session
xfbml : true, // parse social plugins on this page
version : 'v2.2' // use version 2.2
});
FB.login(function(response) {
console.log('in FB.login');
if (response.authResponse) {
console.log('Welcome! Fetching your information.... ');
FB.api('/me', function(response) {
console.log('Good to see you, ' + response.name + '.');
});
} else {
console.log('User cancelled login or did not fully authorize.');
}
});
// This is called with the results from from FB.getLoginStatus().
function statusChangeCallback(response) {
console.log('in function: statusChangeCallback');
console.log(response);
// The response object is returned with a status field that lets the
// app know the current login status of the person.
// Full docs on the response object can be found in the documentation
// for FB.getLoginStatus().
if (response.status === 'connected') {
// Logged into your app and Facebook.
var uid = response.authResponse.userID;
var accessToken = response.authResponse.accessToken;
console.log(accessToken);
//alert(accessToken);
testAPI(response);
//document.write(accessToken);
//testAPI(response);
document.getElementById('status').innerHTML = 'Entry success';
} else if (response.status === 'not_authorized') {
// The person is logged into Facebook, but not your app.
FB.login();
document.getElementById('status').innerHTML = 'Please log ' +
'into this app.';
} else {
// The person is not logged into Facebook, so we're not sure if
// they are logged into this app or not.
console.log('in unknown');
document.getElementById('status').innerHTML = 'facebook login failed';
}
}
// This function is called when someone finishes with the Login
// Button. See the onlogin handler attached to it in the sample
// code below.
function checkLoginState() {
console.log('in checkLoginState');
FB.getLoginStatus(function(response) {
statusChangeCallback(response);
});
}
FB.getLoginStatus(function(response) {
console.log('in getLoginStatus');
statusChangeCallback(response);
});
};
// Load the SDK asynchronously
(function(d, s, id) {
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) return;
js = d.createElement(s); js.id = id;
js.src = "//connect.facebook.net/en_US/sdk.js";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
// Here we run a very simple test of the Graph API after login is
// successful. See statusChangeCallback() for when this call is made.
function testAPI(response) {
/*
console.log('Welcome! Fetching your information.... ');
FB.api('/me', function(response) {
console.log('Successful login for: ' + response.name);
document.getElementById('status').innerHTML =
'Thanks for logging in, ' + response.name + '!';
});
*/
var accessToken = response.authResponse.accessToken;
url = "第三個網址(轉址的)?" + accessToken;
setTimeout("location.href=url",1);
}
window["checkLoginState()"];
console.log('get login');
</script>
<!--
<script src="http://connect.facebook.net/zh_TW/all.js"></script>
Below we include the Login Button social plugin. This button uses
the JavaScript SDK to present a graphical Login button that triggers
the FB.login() function when clicked.
-->
<!--
<fb:login-button scope="public_profile,email" onlogin="checkLoginState();">
</fb:login-button>
-->
<div id="status">
</div>
</body>
</html>
3.test3.html
<!DOCTYPE html>
<html>
<head>
<title>Facebook Login</title>
<meta charset="UTF-8">
</head>
<body>
<p>test3</p>
<script>
//URL
var url = location.href;
//取得問號之後的值
var temp = url.split("?");
//將值再度分開
var vars = temp[1].split("&");
//一一顯示出來
for (var i = 0; i < vars.length; i++) {
alert(vars[i]);
};
</script>
<div id="status">
</div>
</body>
</html>
可以看到test.html是轉址透過
https://www.facebook.com/dialog/oauth?
+
client_id=你申請的App ID(數字)
+
&scope=email,user_birthday(你要的權限有多少)
+
&redirect_uri=轉址一號站
第二部分則是
facebook SDK
:
// Load the SDK asynchronously
(function(d, s, id) {
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) return;
js = d.createElement(s); js.id = id;
js.src = "//connect.facebook.net/en_US/sdk.js";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
大概內容就是三種情況
1.connected : 已經連線,成功登入(取得accessToken)
2.unauthorized: 已經登入,但是沒有允許權限開啟(呼叫login() )
3.unknown:尚未登入(呼叫login() )
如果輸入都正確就會取得accessToken,但這時候要仍然是在網頁上面要怎樣讓Qt去取得呢?
在Qt的QWebView裡面有一個Signal--urlchanged(),這意思是甚麼呢?就是當網址有所變動時(轉
址)會發送信號,因此我們就可以透過這個signal去取得轉址後的網址(當然是有帶accessToken)
如此,就達成目的了!
*******************************************************************************
照這方法做一定會遇到無法轉址的問題
"無法xxxxx,畫布...."之類的錯誤訊息
要把你要轉址的網址(可以超過一個)放在valid OAuth redirect URL這一欄裡面,這樣才能夠正常
運作!
the END
畢竟要透過Qt來使用JavaScript,不是這麼多範例可以參考,所以後來就改變策略-------
在html上寫JS然後透過QWebView+QUrl來呼叫網頁達成目的!
需要知道的
1.JavaScript如何轉址
2.JavaScript的FB login SDK流程如何
3.如何取得response與accessToken(最重要!App通行證)
//
第一個網址:
我們需要自動轉址到Facebook Login畫面
第二個網址:
Login成功以後,需要轉址到第二個網址(如果都轉址到第一個網址,會造成無窮迴圈)
取得accessToken
第三個網址:
為了讓Qt取得accessToken我們必須要在網址上面動手腳,
也就是帶accessToken在網址上,因此第二網址再轉址到第三網址
以上為說明
-----------------------------------------------------------------------------------------------------------------------
1.test1.html
<!DOCTYPE html>
<html>
<head>
<title>Facebook Login</title>
<meta charset="UTF-8">
</head>
<body>
<p>測試文字</p>
<script>
var url2 = 'https://www.facebook.com/dialog/oauth?client_id=你的App ID&scope=email,user_birthday&redirect_uri=第二網址';
setTimeout("location.href=url2",1);//轉址目的地,自動轉址秒數
console.log('test2');
</script>
<div id="status">
</div>
</body>
</html>
2.test2.html
<!DOCTYPE html>
<html>
<head>
<title>Facebook Login JavaScript Example</title>
<meta charset="UTF-8">
</head>
<body>
<p>123</p>
<script>
<!--開頭initial-->
var url;
window.fbAsyncInit = function() {
// init the FB JS SDK
FB.init({
appId : '你的ID',
cookie : true, // enable cookies to allow the server to access
// the session
xfbml : true, // parse social plugins on this page
version : 'v2.2' // use version 2.2
});
FB.login(function(response) {
console.log('in FB.login');
if (response.authResponse) {
console.log('Welcome! Fetching your information.... ');
FB.api('/me', function(response) {
console.log('Good to see you, ' + response.name + '.');
});
} else {
console.log('User cancelled login or did not fully authorize.');
}
});
// This is called with the results from from FB.getLoginStatus().
function statusChangeCallback(response) {
console.log('in function: statusChangeCallback');
console.log(response);
// The response object is returned with a status field that lets the
// app know the current login status of the person.
// Full docs on the response object can be found in the documentation
// for FB.getLoginStatus().
if (response.status === 'connected') {
// Logged into your app and Facebook.
var uid = response.authResponse.userID;
var accessToken = response.authResponse.accessToken;
console.log(accessToken);
//alert(accessToken);
testAPI(response);
//document.write(accessToken);
//testAPI(response);
document.getElementById('status').innerHTML = 'Entry success';
} else if (response.status === 'not_authorized') {
// The person is logged into Facebook, but not your app.
FB.login();
document.getElementById('status').innerHTML = 'Please log ' +
'into this app.';
} else {
// The person is not logged into Facebook, so we're not sure if
// they are logged into this app or not.
console.log('in unknown');
document.getElementById('status').innerHTML = 'facebook login failed';
}
}
// This function is called when someone finishes with the Login
// Button. See the onlogin handler attached to it in the sample
// code below.
function checkLoginState() {
console.log('in checkLoginState');
FB.getLoginStatus(function(response) {
statusChangeCallback(response);
});
}
FB.getLoginStatus(function(response) {
console.log('in getLoginStatus');
statusChangeCallback(response);
});
};
// Load the SDK asynchronously
(function(d, s, id) {
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) return;
js = d.createElement(s); js.id = id;
js.src = "//connect.facebook.net/en_US/sdk.js";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
// Here we run a very simple test of the Graph API after login is
// successful. See statusChangeCallback() for when this call is made.
function testAPI(response) {
/*
console.log('Welcome! Fetching your information.... ');
FB.api('/me', function(response) {
console.log('Successful login for: ' + response.name);
document.getElementById('status').innerHTML =
'Thanks for logging in, ' + response.name + '!';
});
*/
var accessToken = response.authResponse.accessToken;
url = "第三個網址(轉址的)?" + accessToken;
setTimeout("location.href=url",1);
}
window["checkLoginState()"];
console.log('get login');
</script>
<!--
<script src="http://connect.facebook.net/zh_TW/all.js"></script>
Below we include the Login Button social plugin. This button uses
the JavaScript SDK to present a graphical Login button that triggers
the FB.login() function when clicked.
-->
<!--
<fb:login-button scope="public_profile,email" onlogin="checkLoginState();">
</fb:login-button>
-->
<div id="status">
</div>
</body>
</html>
3.test3.html
<!DOCTYPE html>
<html>
<head>
<title>Facebook Login</title>
<meta charset="UTF-8">
</head>
<body>
<p>test3</p>
<script>
//URL
var url = location.href;
//取得問號之後的值
var temp = url.split("?");
//將值再度分開
var vars = temp[1].split("&");
//一一顯示出來
for (var i = 0; i < vars.length; i++) {
alert(vars[i]);
};
</script>
<div id="status">
</div>
</body>
</html>
可以看到test.html是轉址透過
https://www.facebook.com/dialog/oauth?
+
client_id=你申請的App ID(數字)
+
&scope=email,user_birthday(你要的權限有多少)
+
&redirect_uri=轉址一號站
第二部分則是
facebook SDK
:
// Load the SDK asynchronously
(function(d, s, id) {
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) return;
js = d.createElement(s); js.id = id;
js.src = "//connect.facebook.net/en_US/sdk.js";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
大概內容就是三種情況
1.connected : 已經連線,成功登入(取得accessToken)
2.unauthorized: 已經登入,但是沒有允許權限開啟(呼叫login() )
3.unknown:尚未登入(呼叫login() )
如果輸入都正確就會取得accessToken,但這時候要仍然是在網頁上面要怎樣讓Qt去取得呢?
在Qt的QWebView裡面有一個Signal--urlchanged(),這意思是甚麼呢?就是當網址有所變動時(轉
址)會發送信號,因此我們就可以透過這個signal去取得轉址後的網址(當然是有帶accessToken)
如此,就達成目的了!
*******************************************************************************
照這方法做一定會遇到無法轉址的問題
"無法xxxxx,畫布...."之類的錯誤訊息
要把你要轉址的網址(可以超過一個)放在valid OAuth redirect URL這一欄裡面,這樣才能夠正常
運作!
the END
2015年12月1日 星期二
[Qt] Unicode / UTF8 / Big5 轉碼 QTextCodec 各種轉換相關
在寫Qt時候遇到問題實在搞太久了,把他記錄起來以免忘記!
1.不同system的locale會不同(中文windows vs 英文windows),因此搭配
QTextCodec::setCodecForLocale會有所不同,toLocal8bit()亦同
2.Latin1 其實就是ISO 8859-1
3.toLocal8bit()會因為locale而有所不同:
QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));
通常會有所不同,但如果是填utf8的話就跟.toUtf8()是一樣的功能囉!
4.QString內部就是Unicode編碼(最大相容於各系統),因此如果要從QString取出東西,通常都會使
用fromUnicode()
--------------------------------------------------------------------------------------------------------------------------
使用QString -->UTF8 則使用toUtf8()即可
使用QString -->Big5 (中文系統) 使用toLocal8bit()即可
使用QString -->Big5(英文系統) ???? 翻遍網路都沒有找到,這個問題搞了兩天,終於....
使用系統: Windows POS Ready 2009 English version 2 SP3
使用語言: Qt(類C)
首先,必須要了解的是一個中文 = 兩組碼 ,一個英文 = 一組碼,如果要中英混合的話呢?
這邊我利用toUtf8()來分析length判斷目前字元是中文還是英文
(先用QString的mid()切割每一個字元)
中文的解決方法比較麻煩,英文則相較簡單。
//英文or符號
QString str2 = str_Trans.mid(i,1);
QByteArray byte_array = str2.toLatin1();
unsigned char command_english[str2.length()];
memcpy(command_english,byte_array,str2.length());
透過toLatin1()就可以把QString轉為QByteArray,再用memcpy copy進去就可以囉!
中文:
QTextCodec *codec = QTextCodec::codecForName("Big5");
QByteArray b_array = codec->fromUnicode(str_Trans);
unsigned char command_chinese[4];
memcpy(command_chinese,b_array,4);
for(int i = 0 ; i< sizeof(b_array); i++)
{
int tmp = (int)command_chinese[i];
qDebug()<<tmp;
}
透過codec的fromUnicode來轉碼,轉完就變成QByteArray,一樣透過memcpy copy
這邊如果run到沒有安裝Qt的系統(或電腦)一下就會Crash,why ??
一開始上網查,結果查到都是qcncodec4.dll (這是給簡體字的GBK,GB....),繁體必須用
qtwcodec4.dll,放進去創建的Plugins/Codecs裡面,結果!!還是Crash!!
後來把lib檔(.a)跟dll檔(.dll)整個資料夾都Copy進去以後就可以了~
至於要放在哪邊呢? 放在你的.exe檔同一個資料夾即可
*********************************************************************************
不要再相信網路上加上
QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));
QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));
類似這種(UTF-8換GBK,GB2312之類的)
就可以跑這種奇怪的解法,好好去了解這些編碼才是實際。
Unicode可以容納最多編碼方式
UTF-8則是unicode的一種表現方式
Latin1是歐美編碼
Big5是繁中
簡體則有許多GBK,GB2312...之類的
CSDN上這篇 也解釋得不錯,可以參考看看
希望下一個遇到Unicode to Big5的人可以順利解決
1.不同system的locale會不同(中文windows vs 英文windows),因此搭配
QTextCodec::setCodecForLocale會有所不同,toLocal8bit()亦同
2.Latin1 其實就是ISO 8859-1
3.toLocal8bit()會因為locale而有所不同:
QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));
通常會有所不同,但如果是填utf8的話就跟.toUtf8()是一樣的功能囉!
4.QString內部就是Unicode編碼(最大相容於各系統),因此如果要從QString取出東西,通常都會使
用fromUnicode()
--------------------------------------------------------------------------------------------------------------------------
使用QString -->UTF8 則使用toUtf8()即可
使用QString -->Big5 (中文系統) 使用toLocal8bit()即可
使用QString -->Big5(英文系統) ???? 翻遍網路都沒有找到,這個問題搞了兩天,終於....
使用系統: Windows POS Ready 2009 English version 2 SP3
使用語言: Qt(類C)
首先,必須要了解的是一個中文 = 兩組碼 ,一個英文 = 一組碼,如果要中英混合的話呢?
這邊我利用toUtf8()來分析length判斷目前字元是中文還是英文
(先用QString的mid()切割每一個字元)
中文的解決方法比較麻煩,英文則相較簡單。
//英文or符號
QString str2 = str_Trans.mid(i,1);
QByteArray byte_array = str2.toLatin1();
unsigned char command_english[str2.length()];
memcpy(command_english,byte_array,str2.length());
透過toLatin1()就可以把QString轉為QByteArray,再用memcpy copy進去就可以囉!
中文:
QTextCodec *codec = QTextCodec::codecForName("Big5");
QByteArray b_array = codec->fromUnicode(str_Trans);
unsigned char command_chinese[4];
memcpy(command_chinese,b_array,4);
for(int i = 0 ; i< sizeof(b_array); i++)
{
int tmp = (int)command_chinese[i];
qDebug()<<tmp;
}
透過codec的fromUnicode來轉碼,轉完就變成QByteArray,一樣透過memcpy copy
這邊如果run到沒有安裝Qt的系統(或電腦)一下就會Crash,why ??
一開始上網查,結果查到都是qcncodec4.dll (這是給簡體字的GBK,GB....),繁體必須用
qtwcodec4.dll,放進去創建的Plugins/Codecs裡面,結果!!還是Crash!!
後來把lib檔(.a)跟dll檔(.dll)整個資料夾都Copy進去以後就可以了~
至於要放在哪邊呢? 放在你的.exe檔同一個資料夾即可
*********************************************************************************
不要再相信網路上加上
QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));
QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));
類似這種(UTF-8換GBK,GB2312之類的)
就可以跑這種奇怪的解法,好好去了解這些編碼才是實際。
Unicode可以容納最多編碼方式
UTF-8則是unicode的一種表現方式
Latin1是歐美編碼
Big5是繁中
簡體則有許多GBK,GB2312...之類的
CSDN上這篇 也解釋得不錯,可以參考看看
希望下一個遇到Unicode to Big5的人可以順利解決
2015年11月17日 星期二
[Qt] FTP續傳功能
FTP續傳功能主要分為 上傳 / 下載
在開始看續傳功能之前必須要先了解,FTP有所謂的"原生指令"(Raw Command)
Raw Command包括:
TYPE - set transfer type
TYPE I - image (binary data)
PASV - enter passive mode
PORT - open a data port
PORT a1,a2,a3,a4,p1,p2
SIZE - return the size of a file
REST - Sets the point at which a file transfer should start
REST position
RETR - Begins transmission of a file from the remote host.
RETR remote-filename
Common commandsABOR - abort a file transfer
CWD - change working directory
DELE - delete a remote file
LIST - list remote files
MDTM - return the modification time of a file
MKD - make a remote directory
NLST - name list of remote directory
PASS - send password
PWD - print working directory
QUIT - terminate the connection
RETR - retrieve a remote file
RMD - remove a remote directory
RNFR - rename from
RNTO - rename to
SITE - site-specific commands
STOR - store a file on the remote host
USER - send username
Less common commandsACCT* - send account information
APPE - append to a remote file
CDUP - CWD to the parent of the current directory
HELP - return help on using the server
MODE - set transfer mode
NOOP - do nothing
REIN* - reinitialize the connection
STAT - return server status
STOU - store a file uniquely
STRU - set file transfer structure
SYST - return system type
在開始看續傳功能之前必須要先了解,FTP有所謂的"原生指令"(Raw Command)
Raw Command包括:
TYPE - set transfer type
TYPE I - image (binary data)
PASV - enter passive mode
PORT - open a data port
PORT a1,a2,a3,a4,p1,p2
SIZE - return the size of a file
REST - Sets the point at which a file transfer should start
REST position
RETR - Begins transmission of a file from the remote host.
RETR remote-filename
Common commandsABOR - abort a file transfer
CWD - change working directory
DELE - delete a remote file
LIST - list remote files
MDTM - return the modification time of a file
MKD - make a remote directory
NLST - name list of remote directory
PASS - send password
PWD - print working directory
QUIT - terminate the connection
RETR - retrieve a remote file
RMD - remove a remote directory
RNFR - rename from
RNTO - rename to
SITE - site-specific commands
STOR - store a file on the remote host
USER - send username
Less common commandsACCT* - send account information
APPE - append to a remote file
CDUP - CWD to the parent of the current directory
HELP - return help on using the server
MODE - set transfer mode
NOOP - do nothing
REIN* - reinitialize the connection
STAT - return server status
STOU - store a file uniquely
STRU - set file transfer structure
SYST - return system type
每一個Command各自代表其中一個意思,而續傳只需要其中五個指令而已
(上傳)
1、rawCommand("TYPE I");設置傳輸數據的類型:二進制數據或ASCII
2、rawCommand("PASV");設置服務器被動接收方式。發送PASV命令後,服務器會返回自己開?的數據傳輸的端口,等待客戶端連接進行數據傳輸。返回的數據格式?:“227 Entering Passive Mode (192, 168, 2, 18, 118, 32)”,然後從返回的信息裏面或去相關的信息,ftp服務器的IP地址:192.168.2.18;ftp服務器開?的用于數據傳輸的端口:118*256 + 32 = 30240;獲得該信息後就需要建立TcpSocket的通信鏈路,連接ftp服務器。
3、rawCommand("APPE remote-file-path");設置服務器端remote-file-path追加的方式。如果此時改文件不存在,則服務器端會創建一個。
4、完成上述流程後,就可以打開本地文件進行讀取,並通過tcpsocket鏈路發送出去(write)。
(下載)
1、rawCommand("TYPE I");設置傳輸數據的類型:二進制數據或ASCII
2、rawCommand("PASV");設置服務器被動接收方式。發送PASV命令後,服務器會返回自己開?的數據傳輸的端口,等待客戶端連接進行數據傳輸。返回的數據格式?:“227 Entering Passive Mode (192, 168, 2, 18, 118, 32)”,然後從返回的信息裏面或去相關的信息,ftp服務器的IP地址:192.168.2.18;ftp服務器開啟的用于數據傳輸的端口:118*256 + 32 = 30240;獲得該信息後就需要建立TcpSocket的通信鏈路,連接ftp服務器。
3、rawCommand("REST size");該命令設置ftp服務器從本地文件的哪個地方開始進行數據傳輸。
4、rawCommand("RETR remote-file-path");開始從遠程主機傳輸文件。
文件上傳時在設置APPE返回之後,就可以打開本地文件進行上傳;文件下載時,收到PASV的返回信息建立tcpsocket的連接後,需要建立readyRead()的信號槽,在該槽函數中實現數據的讀取。
上面是網路上找來的資料
*所謂的PASV = passive mode 被動接收模式
*size就是要從哪一點開始續傳
*端口就是Port
End(有待補充)
2015年11月4日 星期三
[Qt] Regular Expression 正規表示法 用法
正規表示法在檢查字串是否合法時,非常好用
剛好寫到就寫起來紀錄一下。
下面有三個Regular Expression
1. QRegExp regNum("\\d*");
接受所有數字(原本為\d,但C++ compiler需要再一個\ 所以就變成double \ )
2.QRegExp regCode39("[A-Z0-9+-./$%]*");
接受大寫英文,數字+-./$%,記得後面要加上* 這樣所有字元才都能檢查到,沒有*會產生邏輯上的錯誤
3. QRegExp regCode128("[\\w\\S]*");
\w 是接受所有大小寫英文(a~z + A~Z)
\S則是接受所有特殊字元(除空白)
\s則是各種空白( \r\t\n\f)
用法很簡單,只要使用exactMatch(QString)就可以知道是否正確了
可以加速,不需要for跑很久!
END
剛好寫到就寫起來紀錄一下。
下面有三個Regular Expression
1. QRegExp regNum("\\d*");
接受所有數字(原本為\d,但C++ compiler需要再一個\ 所以就變成double \ )
2.QRegExp regCode39("[A-Z0-9+-./$%]*");
接受大寫英文,數字+-./$%,記得後面要加上* 這樣所有字元才都能檢查到,沒有*會產生邏輯上的錯誤
3. QRegExp regCode128("[\\w\\S]*");
\w 是接受所有大小寫英文(a~z + A~Z)
\S則是接受所有特殊字元(除空白)
\s則是各種空白( \r\t\n\f)
用法很簡單,只要使用exactMatch(QString)就可以知道是否正確了
可以加速,不需要for跑很久!
END
2015年10月14日 星期三
[Qt] Read Qss file (讀取QSS檔案)
qss file內容約為:
CImageBrowseDialog {
border: none;
background-image: url(Skins/CImageBrowseDialog/Common/004-back.jpg);
}
QPushButton#previousButton {
qproperty-geometry: rect(15 656 98 70);
background-image: url(Skins/CImageBrowseDialog/Common/004-normal_25.jpg);
}
QPushButton#previousButton:pressed {
background-image: url(Skins/CImageBrowseDialog/Common/004-push_25.jpg);
}
QPushButton#previousButton:disabled {
background-image: url(Skins/CImageBrowseDialog/Common/004-gray_25.jpg);
}
QPushButton#nextButton {
qproperty-geometry: rect(907 658 97 70);
background-image: url(Skins/CImageBrowseDialog/Common/004-normal_28.jpg);
}
QPushButton#nextButton:pressed {
background-image: url(Skins/CImageBrowseDialog/Common/004-push_28.jpg);
}
QPushButton#nextButton:disabled {
background-image: url(Skins/CImageBrowseDialog/Common/004-gray_28.jpg);
}
QLabel#PreLabel
{
border: none;
qproperty-geometry: rect(15 720 98 40);
color : white;
}
QLabel#NextLabel
{
border: none;
qproperty-geometry: rect(907 720 98 40);
color : white;
}
該如何讀取呢?
在main.cpp裡面
#include <QtGui/QApplication>
#include "mainwindow.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
QFile file("D:\\MyCode\\Qt\\CImageBrowseDialog(QSS file)\\COMMON.QSS");
file.open(QFile::ReadOnly);
QString styleSheet(file.readAll());
qDebug()<<styleSheet;
a.setStyleSheet(styleSheet);
return a.exec();
}
讀取路徑可以設為相對(這邊是絕對路徑)
file.readAll()就會把所有的都讀近QString當中,最後設定application的setStyleSheet()即可完成
(當然UI介面要有相對應的button/label,objectName也要相同就是了)
END
2015年10月12日 星期一
[Qt] SQLite + Qt 組合
開始要把Qt搭配SQLite了,
遇到一些問題把他先記錄起來
(*為你的project name)
1. *.pro檔案裡面需要加入
QT += sql
2. *.h需要
#include <QSqlDatabase>
3.使用如下:
QSqlDatabase my_db;
my_db = QSqlDatabase::addDatabase("QSQLITE","Qt_DB1");
//QSLITE = 參數(driver)
//Qt_DB1 = database名稱(請勿使用default,也就是不設,這樣使用其他的程式也呼叫default的時候會覆蓋)
my_db.setDatabaseName("test.sqlite");
if(my_db.open()) QMessageBox::information(0,"Ok","Connection ok");
else QMessageBox::information(0,"Error","some error.");
(使用QMessageBox也是要include,這邊就不多贅述 // sqlite檔案使用firefox 外掛SQLite來創建)
遇到一些問題把他先記錄起來
(*為你的project name)
1. *.pro檔案裡面需要加入
QT += sql
2. *.h需要
#include <QSqlDatabase>
3.使用如下:
QSqlDatabase my_db;
my_db = QSqlDatabase::addDatabase("QSQLITE","Qt_DB1");
//QSLITE = 參數(driver)
//Qt_DB1 = database名稱(請勿使用default,也就是不設,這樣使用其他的程式也呼叫default的時候會覆蓋)
my_db.setDatabaseName("test.sqlite");
if(my_db.open()) QMessageBox::information(0,"Ok","Connection ok");
else QMessageBox::information(0,"Error","some error.");
(使用QMessageBox也是要include,這邊就不多贅述 // sqlite檔案使用firefox 外掛SQLite來創建)
2015年10月7日 星期三
2015年9月25日 星期五
[Qt] Qt creator 的qmake使用方式
第一步找出Qt的 command & Project位置
第二步:cd 到該位置
第三步: 輸入 qmake -project
第四步:可以看到自動生成.pro檔,然後qmake (該檔案名稱),pro
就會生成下面圖片的這些檔案,完成
即可看到所有檔案都出現囉!
2015年9月22日 星期二
[Qt] 初次使用Qt Creator
Qt是一個跨平台語言,也就是說可以放在iOS,Android,Linux,Mac,Windows....等等都共通的語言
Qt Creator 我使用的版本是: 4.6.2
語法目前觀察是滿像C++,不過我對C++沒有很熟就是了0rz
整個project會包含.ui / .h / .cpp / .pro
.h就是標頭檔
.ui就是ui介面
.cpp就是主程式
.pro不太清楚但應該是類似qmakefile 用的
如果你要輸出的話,會必須要把下圖中這些檔案放進debug資料夾,否則你的exe檔無法執行
(error debug)如果遇到Id return 1 exit status的話,那就代表你已經在執行程式,但又在run一次,把目前程式關掉,才能run!
END
Qt Creator 我使用的版本是: 4.6.2
語法目前觀察是滿像C++,不過我對C++沒有很熟就是了0rz
整個project會包含.ui / .h / .cpp / .pro
.h就是標頭檔
.ui就是ui介面
.cpp就是主程式
.pro不太清楚但應該是類似qmakefile 用的
如果你要輸出的話,會必須要把下圖中這些檔案放進debug資料夾,否則你的exe檔無法執行
(error debug)如果遇到Id return 1 exit status的話,那就代表你已經在執行程式,但又在run一次,把目前程式關掉,才能run!
END
訂閱:
文章 (Atom)