簡體   English   中英

將 QML 連接到 C++ 插槽

[英]Connecting QML to C++ slot

我創建了一個應用程序,每次加載器的源發生變化時都會自動截屏! 我正在嘗試將 QML 信號(screenshot())連接到 CPP 插槽(take_screenshot())。 但是,盡管加載程序的源正在更改並且我也收到了控制台日志,但從未調用過 take_screenshot() 函數! 這是我的 cpp.h

 class MyClass : public QObject
 {
    Q_OBJECT
public:
MyClass(std::shared_ptr<QQmlApplicationEngine> engin)
    : m_engine(engin)
{
    QObject* root = m_engine->rootObjects()[0];
    Q_ASSERT(root != nullptr);
    QObject::connect(root, SIGNAL(screenshot()),
                     this, SLOT(take_screenshot()));
}

public slots:
int take_screenshot()
{
        QString currentDateTime = QDateTime::currentDateTime().toString( "MMMM d, yyyy, HH:mm:ss");
        QScreen *screen;
        QPixmap pixmap;
        screen = QGuiApplication::primaryScreen();
        pixmap = screen->grabWindow(0);
        QString screenshotPath = QDir::currentPath();
        QString screenShotFileName = QString("%1/%2.png").arg(screenshotPath).arg(currentDateTime);

        if (!screenShotFileName.isEmpty())
        {
            pixmap.save(screenShotFileName);
            return 1;
        }
        else
            return 0;
}

private:
std::shared_ptr<QQmlApplicationEngine> m_engine;
};

這是我的 main.qml

Window {
id: mainWindow
visible: true
width: 640
height: 480
title: qsTr("Hello World")

signal screenshot()
Loader {
         id: pageLoader
         objectName: "pageLoader"
         anchors.fill: parent
         onSourceChanged: {
         console.log("onSourceChanged_source :", pageLoader.source)
                mainWindow.screenshot()
            }
         Component.onCompleted:{
                console.log("onCompleted!", pageLoader.source)
                mainWindow.screenshot()
            }
        }
   }

不要在 C++ 中訪問 QML 對象,因為您可能會遇到意外行為。 在這種情況下,最好將對象導出到 QML,例如創建一個單例:

實用程序.h

#ifndef UTILS_H
#define UTILS_H

#include <QGuiApplication>
#include <QObject>
#include <QPixmap>
#include <QQmlApplicationEngine>
#include <QScreen>
#include <QDateTime>
#include <QDir>

class Utils : public QObject
{
    Q_OBJECT
public:
    using QObject::QObject;
public slots:
    bool screenshot(){
        qDebug() << __PRETTY_FUNCTION__;
        QString currentDateTime = QDateTime::currentDateTime().toString( "MMMM d, yyyy, HH:mm:ss");
        QString screenshotPath = QDir::currentPath();
        QString filename = QString("%1/%2.png").arg(screenshotPath).arg(currentDateTime);
        if(QScreen *screen = QGuiApplication::primaryScreen()){
            QPixmap pixmap = screen->grabWindow(0);
            return pixmap.save(filename));
        }
        return false;
    }
};
#endif // UTILS_H

主程序

#include "utils.h"

#include <QGuiApplication>
#include <QQmlApplicationEngine>


int main(int argc, char *argv[])
{
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif

    QGuiApplication app(argc, argv);

    QScopedPointer<Utils> utils(new Utils);
    qmlRegisterSingletonInstance("Utils", 1, 0, "Utils", utils.get());

    QQmlApplicationEngine engine;

    const QUrl url(QStringLiteral("qrc:/main.qml"));
    QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                     &app, [url](QObject *obj, const QUrl &objUrl) {
        if (!obj && url == objUrl)
            QCoreApplication::exit(-1);
    }, Qt::QueuedConnection);
    engine.load(url);
    return app.exec();
}

主文件

import QtQuick 2.15
import QtQuick.Window 2.15

import Utils 1.0

Window {
    id: mainWindow
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")
    Loader {
        id: pageLoader
        anchors.fill: parent
        onSourceChanged: {
            console.log("onSourceChanged_source :", pageLoader.source)
            Utils.screenshot()
        }
        Component.onCompleted:{
            console.log("onCompleted!", pageLoader.source)
            var res = Utils.screenshot()
            console.log(res)
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM