この記事では、QtとQMLを使用して、メインウィンドウの位置とサイズを操作する方法を紹介します。
サブウィンドウのQMLファイル
まず、メインウィンドウの表示位置とサイズを制御するためのボタンを配置したSubWindow.qmlを作成します。以下にそのコードを示します。
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Window 2.15
import QtQuick.Layouts 1.15
Window {
id: subWindow
width: 300
height: 200
title: "Sub Window"
visible: false
x: 0
y: screenHeight - height
color: "black"
flags: Qt.WindowStaysOnTopHint
// Properties for setting the position of the main window
property int xPosition: mainWindow.x
property int yPosition: mainWindow.y
property int wSize: mainWindow.width
property int hSize: mainWindow.height
onXPositionChanged: mainWindow.x = xPosition
onYPositionChanged: mainWindow.y = yPosition
onWSizeChanged: mainWindow.width = wSize
onHSizeChanged: mainWindow.height = hSize
Column {
anchors.centerIn: parent
Row {
Layout.alignment: Qt.AlignVCenter
Label {
text: "x"
}
Button {
text: "-"
onClicked: xField.text = parseInt(xField.text) - 1
}
TextField {
id: xField
text: mainWindow.x
inputMethodHints: Qt.ImhDigitsOnly
onTextChanged: xPosition = parseInt(text)
}
Button {
text: "+"
onClicked: xField.text = parseInt(xField.text) + 1
}
}
Row {
Layout.alignment: Qt.AlignVCenter
Label {
text: "y"
}
Button {
text: "-"
onClicked: yField.text = parseInt(yField.text) - 1
}
TextField {
id: yField
text: mainWindow.y
inputMethodHints: Qt.ImhDigitsOnly
onTextChanged: yPosition = parseInt(text)
}
Button {
text: "+"
onClicked: yField.text = parseInt(yField.text) + 1
}
}
Row {
Label {
text: "w"
}
Button {
text: "-"
onClicked: wField.text = parseInt(wField.text) - 1
}
TextField {
id: wField
text: mainWindow.width
inputMethodHints: Qt.ImhDigitsOnly
onTextChanged: wSize = parseInt(text)
}
Button {
text: "+"
onClicked: wField.text = parseInt(wField.text) + 1
}
}
Row {
Label {
text: "h"
}
Button {
text: "-"
onClicked: hField.text = parseInt(hField.text) - 1
}
TextField {
id: hField
text: mainWindow.height
inputMethodHints: Qt.ImhDigitsOnly
onTextChanged: hSize = parseInt(text)
}
Button {
text: "+"
onClicked: hField.text = parseInt(hField.text) + 1
}
}
}
}
重要なポイントは、次の部分です。
// Properties for setting the position of the main window
property int xPosition: mainWindow.x/
property int yPosition: mainWindow.y
property int wSize: mainWindow.width
property int hSize: mainWindow.height
ここではmainWindowのパラメータを取得しています。mainWindowは後ほどmain.cppでQMLに公開します。
メインウィンドウのQML
次に、Main.qmlを作成します。これがメインウィンドウのQMLとなります。
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Window 2.15
import Qt.labs.platform 1.1
import "QML" as QMLComponents
Window {
id: mainWindow
x: 0
y: 0
width: 640
height: 480
visible: true
title: qsTr("Hello World")
flags: Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint
MouseArea {
anchors.fill: parent
hoverEnabled: true
onEntered: {
cursorShape = Qt.BlankCursor
}
}
QMLComponents.SubWindow {
id: subWindow
x: 0
y: screenHeight - height
onVisibleChanged: {
if (!visible) {
mainWindow.flags = Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint
}
}
}
Shortcut {
sequence: (Qt.platform.os === "windows") ? "Ctrl+," : "Ctrl+,"
onActivated: {
subWindow.visible = true
mainWindow.flags = Qt.FramelessWindowHint
}
}
}
以下が注目すべきポイントです。
flags: Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint
上記のコードにより、メインウィンドウはタイトルバーが非表示になり、また常に最前面に表示されるように設定されます。
MouseArea {
anchors.fill: parent
hoverEnabled: true
onEntered: {
cursorShape = Qt.BlankCursor
}
}
これによりメインウィンドウ上でマウスカーソルが表示されなくなります。
QMLComponents.SubWindow {
id: subWindow
x: 0
y: screenHeight - height
onVisibleChanged: {
if (!visible) {
mainWindow.flags = Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint
}
}
}
・・・
}
上記コードで先ほど作成したSubWindow.qmlを登録しています。また、サブウィンドウが非表示になったタイミングで、メインウィンドウをタイトルバーを非表示にし、最前面に表示するようにしています。
Shortcut {
sequence: (Qt.platform.os === "windows") ? "Ctrl+," : "Ctrl+,"
onActivated: {
subWindow.visible = true
mainWindow.flags = Qt.FramelessWindowHint
}
}
最後に、ショートカットキーを設定しています。Ctrl+,を押すとサブウィンドウが表示されるように設定しています。
以上がウィンドウの位置とサイズを操作するための主な設定です。これらを活用すれば、QtとQMLを用いて柔軟なウィンドウ操作が可能になります。
メイン関数
main.cppでスクリーンサイズを取得し、それとメインウィンドウをQMLに公開する方法を紹介します。以下にそのコードを示します。
#include <QGuiApplication>#include <QQmlApplicationEngine>#include <QQmlContext>#include <QScreen>int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
// Get default screen
QScreen *screen = QGuiApplication::primaryScreen();
// Get screen width and height
int screenWidth = screen->availableSize().width();
int screenHeight = screen->availableSize().height();
QQmlApplicationEngine engine;
QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed,
&app, []() { QCoreApplication::exit(-1); },
Qt::QueuedConnection);
// Screen sizes published in QML
engine.rootContext()->setContextProperty("screenWidth", screenWidth);
engine.rootContext()->setContextProperty("screenHeight", screenHeight);
engine.loadFromModule("SubWindow", "Main");
// Make the mainWindow object available to QML
QObject *mainWindow = engine.rootObjects().value(0);
engine.rootContext()->setContextProperty("mainWindow", mainWindow);
return app.exec();
}
以下にこのコードの主要な部分を紹介します。
// Screen sizes published in QML
engine.rootContext()->setContextProperty("screenWidth", screenWidth);
engine.rootContext()->setContextProperty("screenHeight", screenHeight);
ここではスクリーンのサイズをQMLに公開しています。これにより、QMLの任意の場所でスクリーンサイズにアクセスすることが可能になります。
// Make the mainWindow object available to QML
QObject *mainWindow = engine.rootObjects().value(0);
engine.rootContext()->setContextProperty("mainWindow", mainWindow);
ここではメインウィンドウオブジェクトをQML側で使用できるように公開しています。これにより、QMLから直接メインウィンドウオブジェクトにアクセスし、それを制御することが可能になります。
これらの手法を用いることで、C++のコードとQMLを効果的に連携させることができます。これにより、QtとQMLを使用したアプリケーションの開発がより柔軟かつ効率的になります。