Skip to content

Instantly share code, notes, and snippets.

@yossi-tahara
Last active July 25, 2020 09:43
Show Gist options
  • Save yossi-tahara/01a5118a9271a56aee9847a18a70601a to your computer and use it in GitHub Desktop.
Save yossi-tahara/01a5118a9271a56aee9847a18a70601a to your computer and use it in GitHub Desktop.
第4回 QMLで記述したウィンドウをC++から制御する
QT += quick
CONFIG += c++11
# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Refer to the documentation for the
# deprecated API to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
WindowBase.cpp \
main.cpp \
MainWindow.cpp
HEADERS += \
MainWindow.h \
WindowBase.h
RESOURCES += qml.qrc
# Additional import path used to resolve QML modules in Qt Creator's code model
QML_IMPORT_PATH =
# Additional import path used to resolve QML modules just for Qt Quick Designer
QML_DESIGNER_IMPORT_PATH =
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
©2020 Theoride Technology (http://theolizer.com/) All Rights Reserved.
Boost Software License - Version 1.0 - August 17th, 2003
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
#include <QGuiApplication>
#include "MainWindow.h"
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
try
{
QGuiApplication app(argc, argv);
MainWindow aMainWindow;
aMainWindow.show();
return app.exec();
}
catch (MyException& e)
{
qDebug() << "MyException :" << e.what();
}
return EXIT_FAILURE;
}
#include <QCoreApplication>
#include "MainWindow.h"
// ***************************************************************************
// コンストラクタ
// ***************************************************************************
MainWindow::MainWindow() :
WindowBase("qrc:/MainWindow.qml")
{
mQmlWindow->setProperty("label0Text", u8"C++から設定した文字列");
connect(mQmlWindow, SIGNAL(button0Signal(QString)),
this, SLOT(button0Slot(QString)));
}
// ***************************************************************************
// デストラクタ
// ***************************************************************************
MainWindow::~MainWindow()
{
}
// ***************************************************************************
// button0の処理
// ***************************************************************************
void MainWindow::button0Slot(QString const& iMessage)
{
qDebug() << "button0Slot():" << iMessage;
QVariant returnValue;
bool ret = QMetaObject::invokeMethod
(
mQmlWindow, "setTextInput0",
Qt::DirectConnection,
Q_RETURN_ARG(QVariant, returnValue),
Q_ARG(QVariant, iMessage+"@")
);
qDebug() << " " << ret << returnValue;
}
#ifndef MAIN_WINDOW_H
#define MAIN_WINDOW_H
#include "WindowBase.h"
class MainWindow : public WindowBase
{
Q_OBJECT
Q_DISABLE_COPY(MainWindow)
public:
explicit MainWindow();
~MainWindow();
signals:
private slots:
void button0Slot(QString const& iMessage);
private:
};
#endif // MAIN_WINDOW_H
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
ApplicationWindow
{
objectName: "root"
visible: false
width: 640
height: 480
title: qsTr("Hello World")
// C++ I/F
property alias label0Text: label0.text
signal button0Signal(string iMessage);
function setTextInput0(iText)
{
console.log("setTextInput0():", textInput0.text, " -> ", iText)
textInput0.text=iText
return "returnString";
}
// コンテンツ
ColumnLayout
{
Text
{
id: label0
objectName: "label0"
text: qsTr("デフォルト")
font
{
pixelSize: 20
bold: true
}
}
Button
{
id: button0
objectName: "button0"
text: "Add"
font
{
pixelSize: 20
bold: true
}
onClicked:
{
console.log("button0Signal(): ", textInput0.text)
button0Signal(textInput0.text)
}
}
TextInput
{
id: textInput0
objectName: "textInput0"
text: "Text"
font
{
pixelSize: 20
bold: true
}
}
}
}
<RCC>
<qresource prefix="/">
<file>MainWindow.qml</file>
</qresource>
</RCC>
#include <QCoreApplication>
#include <QDebug>
#include "WindowBase.h"
// ***************************************************************************
// コンストラクタ
// ***************************************************************************
WindowBase::WindowBase(QString const iQmlFile) :
QObject(nullptr),
mQmlWindow(nullptr)
{
// QMLのロード
const QUrl url(iQmlFile);
connect(&mQmlEngine, &QQmlApplicationEngine::objectCreated, this,
[url](QObject *obj, const QUrl &objUrl)
{
if (!obj && url == objUrl)
{
throw MyException("Failed to load qml : " + url.toString());
}
}, Qt::QueuedConnection);
mQmlEngine.load(url);
for (QObject const* obj : mQmlEngine.rootObjects())
{
enumeration(obj);
}
// Windowポインタ獲得
mQmlWindow = dynamic_cast<QQuickWindow*>(mQmlEngine.rootObjects().first());
if (!mQmlWindow)
{
throw MyException("Not found QQuickWindow : " + url.toString());
}
}
// ***************************************************************************
// デストラクタ
// ***************************************************************************
WindowBase::~WindowBase()
{
}
// ***************************************************************************
// デバッグ用
// ***************************************************************************
void WindowBase::enumeration(QObject const* iObject, int iLevel)
{
QMetaObject const* aMetaObject = iObject->metaObject();
qDebug() << QByteArray(iLevel*4, ' ').data() << aMetaObject->className() << " :" << iObject->objectName();
QObjectList const aObjList = iObject->children();
if (aObjList.size() == 0)
return;
for (QObject const* obj : aObjList)
{
enumeration(obj, iLevel+1);
}
}
#ifndef WINDOW_BASE_H
#define WINDOW_BASE_H
#include <QObject>
#include <QQmlApplicationEngine>
#include <QQuickWindow>
#include <QException>
// ***************************************************************************
// QML用ウインドウ・ベース
// ***************************************************************************
//----------------------------------------------------------------------------
// エラー通知用
//----------------------------------------------------------------------------
class MyException : public QException
{
public:
MyException(QString const& iReason) : mReason(iReason.toUtf8()) { }
void raise() const override { throw *this; }
MyException *clone() const override { return new MyException(*this); }
char const* what() const noexcept override { return mReason.data(); }
private:
QByteArray mReason;
};
//----------------------------------------------------------------------------
// 本体
//----------------------------------------------------------------------------
class WindowBase : public QObject
{
Q_OBJECT
Q_DISABLE_COPY(WindowBase)
public:
explicit WindowBase(QString const iQmlFile);
~WindowBase();
// 中継
void show() { mQmlWindow->show(); }
void hide() { mQmlWindow->hide(); }
protected:
QQuickWindow* mQmlWindow;
signals:
private slots:
private:
QQmlApplicationEngine mQmlEngine;
// デバッグ用
void enumeration(QObject const* iObject, int iLevel=0);
};
#endif // WINDOW_BASE_H
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment