Qt on Android:应用截屏
16lz
2022-06-27
在桌面平台上,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专栏”。
更多相关文章
- 在没有内置Google Map add-on的Android真机上如何安装地图程序呢
- Android之路——第三个Android小程序(Android的Activity显示)
- android 代码优化:关闭输出日志
- j2me程序移植入android总结
- [原] Android(安卓)自定义View步骤
- 麦子学院android开发笔记:Android更换RatingBar图片
- Xamarin向iOS和Android引入C# Async支持
- 浅谈Java中Collections.sort对List排序的两种方法
- Python list sort方法的具体使用