Showing a popup without any toplevel window in QtQuick

Viewed 788

I want to make a game overlay to show my custom cross-hair. I want it to be always there with no closing policy.

I used a Popup item in an ApplicationWindow and I set the opacity of it to 0 and the opacity of the pop-up to 1 but it just showed me nothing.I also tried using the pop-up item without any toplevel window but again nothing.

The question is "Is it possible to show an always-on-top popup without any visible top-level window ?"

Your suggestions would be appreciated.

1 Answers

Without a popup window, we can try out with the 'z' property of the QQuickItem. Stack the crosshair always on top of your other items. And if you want to move the crosshair across the screen you can use their 'x,y' properties.

I have tried a simple sample for the same. Used an Image item for crosshair on top of the scroll view. It works as expected. I tried my way. We will see if some other idea's coming in.

Sample code here:

import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 2.2

Window {
    visible: true
    width: 640
    height: 480

    // used here only to indicate image loading is going on
    BusyIndicator {
        id: busyindicatorId
        visible: backgroundImgId.status === Image.Loading ||
                 crossImgId.status === Image.Loading
        anchors.centerIn: parent
    }

    // background item
    ScrollView {
        anchors.fill: parent
        anchors.margins: 10
        clip: true
        visible: !busyindicatorId.visible
        Image {
            id: backgroundImgId
            source: "https://i.ibb.co/ZBNLvzb/andriod.jpg"
        }
    }

    // crosshair item
    Image {
        id:  crossImgId
        z: 1
        width: 100
        height: width
        visible: !busyindicatorId.visible
        source: "https://i.ibb.co/SJFTLwN/cross.png"
        anchors.centerIn: parent
    }
}

Updates Instantiated two windows of that one can be used for crosshair and have to set some window properties(transparent, alwaysontop) to show always on top. Let's have a look at this base code. Sample video

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQuickView>
#include <QScreen>

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;

    QScreen *screen = QGuiApplication::primaryScreen();
    QQuickView view;
    view.setSource(QUrl(QStringLiteral("qrc:/crosshair.qml")));
    view.setX(screen->geometry().width()/2 - view.width()/2);
    view.setY(screen->geometry().height()/2 - view.height()/2);
    view.setColor("transparent");
    view.setFlags(Qt::SubWindow | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
    view.show();

    return app.exec();
}

//////////////// main.qml ////////////////
import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 2.2

Window {
    visible: true
    visibility: "FullScreen"
    objectName: "mainWindow"

    // used here only to indicate image loading is going on
    BusyIndicator {
        id: busyindicatorId
        visible: backgroundImgId.status === Image.Loading
        anchors.centerIn: parent
    }

    // background item
    ScrollView {
        anchors.fill: parent
        anchors.margins: 10
        clip: true
        visible: !busyindicatorId.visible
        Image {
            id: backgroundImgId
            source: "https://i.ibb.co/ZBNLvzb/andriod.jpg"
        }
    }
}

//////////////// crosshair.qml ////////////////
import QtQuick 2.9
import QtQuick.Controls 2.2

Item {
    width: 100
    height: 100
    // crosshair item
    Image {
        width: parent.width
        height: parent.height
        source: "https://i.ibb.co/SJFTLwN/cross.png"
    }
}
Related