Qt on Android:應用截屏,qtandroid
在案頭平台上,QScreen::grabWindow 可以為你的應用截屏,Android 平台上這個不管用了,不過有替代方法。
分兩種情況來說吧, Qt Widgets 與 Qt Quick。
插播廣告,歡迎關注我的訂閱號“程式視界”,掃描下方二維碼即可:
程式視界每周更新一到二篇程式員相關的文章,從心出發,漫談程式員眼中的世界和世界眼中的程式員。
Qt Widgets
最關鍵的就是一個函數: QWidget::render ,這個方法可以把一個 QWidget(包含它的孩子們)的內容渲染到一個 QPixmap 上,然後我們用 QPixmap 的 save 方法就可以儲存了。
下面是關鍵代碼:
void Widget::onGrab(){ QPixmap *pixmap = new QPixmap(size()); render(pixmap); QString savedPath = QStandardPaths::writableLocation(QStandardPaths::PicturesLocation); if(savedPath.isEmpty()) { savedPath = QDir::currentPath(); } m_savedPathLabel->setText(savedPath); m_savedPathLabel->adjustSize(); savedPath += "/grabWidgets.png"; bool ret = pixmap->save(savedPath); if(ret) { m_savedPathLabel->setText("OK."+savedPath); } else { m_savedPathLabel->setText("Failed."+savedPath); }}
onGrab() 方法的前兩行以 widget 的大小建立了一個 QPixmap ,然後調用 render 方法。接下來的代碼是把圖片儲存到 Android 裝置的預設圖片目錄下。
Qt Quick
Qt Quick 應用,都會有一個 QQuickWindow ,而 QQuickWindow 有一個 grabWindow 方法,可以把應用當前視窗的內容儲存為圖片。
這個牽涉到 QML 與 C++ 混合編程了,參考我的《Qt Quick核心編程》,或者“Qt Quick 之 QML 與 C++ 混合編程詳解”。
C++代碼
標頭檔 grabber.h :
class Grabber : public QObject{ Q_OBJECTpublic: Grabber(QObject *parent = 0); Q_INVOKABLE QString grab(QQuickWindow *w);};
源檔案 grabber.cpp 裡的關鍵代碼:
QString Grabber::grab(QQuickWindow *w){ QImage image = w->grabWindow(); if(image.isNull()) return QString(); QString savedPath = QStandardPaths::writableLocation(QStandardPaths::PicturesLocation); if(savedPath.isEmpty()) { savedPath = QDir::currentPath(); } savedPath += "/grabQML.png"; bool ret = image.save(savedPath); if(ret) { return savedPath; } return QString();}
另外需要在 main() 函數中設定一個 QmlContext 的屬性,代碼如下:
Grabber *grabber = new Grabber; engine.rootContext()->setContextProperty("grabber", grabber);
然後我們就可以在 Qml 檔案內使用 Grabber 來了。
QML代碼
我的測試 QML 文檔 main.qml 如下:
import QtQuick 2.2import QtQuick.Window 2.0import QtQuick.Controls 1.1Window { id: rootWin; visible: true; title: qsTr("Hello Grab QML"); objectName: "rootWin"; Text { text: qsTr("Hello Grab QML"); color: "blue"; font.pointSize: 16; anchors.centerIn: parent; } Rectangle { anchors.top: parent.top; anchors.horizontalCenter: parent.horizontalCenter; width: 120; height: 120; color: "blue"; } Text { id: savedPath; anchors.left: parent.left; anchors.bottom: parent.bottom; anchors.bottomMargin: 4; color: "red"; font.pointSize: 12; } Button { id: grab; anchors.bottom: savedPath.top; anchors.bottomMargin: 4; anchors.horizontalCenter: parent.horizontalCenter; text: "Grab"; onClicked: { var saved = grabber.grab(rootWin); if(saved.length == 0){ savedPath.text = "Failed!"; }else{ savedPath.text= "Ok -" + saved; } } }}
我在 grab 按鈕的 onClicked 訊號處理器內調用 grabber.grab() 來完成操作,成功時將路徑顯示出來。
OK,就這麼多了。
想瞭解更多 Qt on Android 內容,可以參考《Qt on Android核心編程》或“Qt on Android專欄”,想瞭解更多 Qt Quick(QML)內容,可以參考《Qt Quick核心編程》或“Qt Quick專欄”。