W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
看到評(píng)論里面有朋友抱怨以前文章里面的例子都是 for Windows 的,沒(méi)有 for Linux 或者 for Mac 的。那么今天就來(lái)說(shuō)說(shuō)跨平臺(tái)的問(wèn)題吧!所謂跨平臺(tái),其實(shí)有兩種含義,一是跨硬件平臺(tái),一是跨軟件平臺(tái)。對(duì)于硬件平臺(tái),很多時(shí)候我們都會(huì)不自覺(jué)的忽略掉,因?yàn)橛布町愲m然很大,但是我們能夠接觸到的卻很少。目前 PC 系列基本都是兼容的,并且編譯器可能會(huì)幫助我們完成這個(gè)問(wèn)題,因此如果你的程序沒(méi)有用到匯編語(yǔ)言,基本很難考慮到這種跨平臺(tái)的支持。但是,如果你的程序需要接觸到硬件,不管是因?yàn)楣δ艿男枰€是因?yàn)樾阅艿男枰?,就不得不考慮這個(gè)問(wèn)題。比如,Photoshop 的顏色處理直接使用匯編語(yǔ)言編寫,以達(dá)到最好性能,這就不得不考慮硬件相關(guān)的問(wèn)題。通常我們說(shuō)跨平臺(tái),更多的只軟件的跨平臺(tái),也就是跨操作系統(tǒng)。現(xiàn)在主流操作系統(tǒng) Windows,Linux/Unix,基本算作是兩大陣營(yíng)吧,它們之間的軟件都是不兼容的,所以這種跨平臺(tái)是我們接觸比較多的。
說(shuō)起跨平臺(tái),就不得不提 Java。這是 Java 的賣點(diǎn)之一:“一次編寫,到處運(yùn)行”。Java 之所以能夠?qū)崿F(xiàn)跨平臺(tái),是因?yàn)?Java 源代碼編譯成一種中間代碼,運(yùn)行 Java 程序,實(shí)際上是在 JVM 中。你編寫出的 Java 程序是跨平臺(tái)的,但是 JVM 不是跨平臺(tái)的,必須根據(jù)你的操作系統(tǒng)選擇 JVM。這是適配器模式的典型應(yīng)用 :-)選擇一個(gè)本身就是跨平臺(tái)的庫(kù),你的工作量就會(huì)小很多,比如 Qt。Qt 已經(jīng)幫我們封裝好很多平臺(tái)相關(guān)的代碼。如果你打開(kāi)一個(gè) Qt 的源代碼,就可能找到很多關(guān)于操作系統(tǒng)的判斷。簡(jiǎn)單來(lái)說(shuō),我們使用 QMainWindow::show() 就可以顯示一個(gè)窗口。在 Windows 上,Qt 必須調(diào)用 Win32 API 完成;在 Linux 上,你就可能需要調(diào)用 GNOME 或者 KDE 的 API。但是,無(wú)論如何,這部分代碼都不是我們關(guān)心的,因?yàn)?Qt 已經(jīng)替我們完成了。所以,如果你的程序沒(méi)有與平臺(tái)相關(guān)的代碼,那么只需要在 Windows 上編譯成功,然后拿到 Linux 上重新編譯一下,通過(guò)一些簡(jiǎn)單測(cè)試,或者還需要調(diào)整一下 UI 比例等等,就可以拿去發(fā)行了。但是,如果有部分代碼不得不依賴操作系統(tǒng),比如我們調(diào)用列出目錄的命令,Windows 下是 dir,而 Linux 下是 ls,這就不得不根據(jù)平臺(tái)進(jìn)行編譯了。這里我們就拿這個(gè)例子嘗試一下。
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
class QProcess;
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void openProcess();
void readResult(int exitCode);
private:
QProcess *p;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include <QProcess>
#include <QPushButton>
#include <QMessageBox>
#include <QTextCodec>
#include "mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
p = new QProcess(this);
QPushButton *bt = new QPushButton("display", this);
connect(bt, SIGNAL(clicked()), this, SLOT(openProcess()));
}
MainWindow::~MainWindow()
{
}
void MainWindow::openProcess()
{
#if defined(Q_OS_WIN32)
p->start("cmd.exe", QStringList() << "/c" << "dir");
#elif defined(Q_OS_LINUX)
p->start("ls", QStringList() << "/home/usr_name");
#endif
connect(p, SIGNAL(finished(int)), this, SLOT(readResult(int)));
}
void MainWindow::readResult(int exitCode)
{
if(exitCode == 0) {
#if defined(Q_OS_WIN32)
QTextCodec* gbkCodec = QTextCodec::codecForName("GBK");
QString result = gbkCodec->toUnicode(p->readAll());
#elif defined(Q_OS_LINUX)
QTextCodec* utfCodec = QTextCodec::codecForName("UTF-8");
QString result = utfCodec->toUnicode(p->readAll());
#endif
QMessageBox::information(this, "dir", result);
}
}
例子和前面是一樣的,我們只是在 cpp 文件中添加了一些代碼。我們使用 #if 這些預(yù)處理指令通過(guò)判斷 Q_OS_WIN32 這樣的宏是否存在,來(lái)生成相應(yīng)的平臺(tái)相關(guān)的代碼。這些宏是在 Qt 中定義好的,我們只需根據(jù)它們是否存在進(jìn)行判斷。這樣,我們的程序就可以在 Windows 和 Linux 下都可以編譯運(yùn)行。進(jìn)行跨平臺(tái)編程,你不得不需要接觸到一些平臺(tái)相關(guān)的東西,比如文字符編碼等,都是需要好好學(xué)習(xí)的。所以建議是盡可能使用 Qt 提供的標(biāo)準(zhǔn)函數(shù)進(jìn)行編程,這樣就不必寫一大堆 if 判斷,代碼也更加清晰。
本文出自 “豆子空間” 博客,請(qǐng)務(wù)必保留此出處 http://devbean.blog.51cto.com/448512/193918
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: