Showing custom popup dialog from c++



  • Hi,

    I'm trying to add a general way of showing popup dialogs, messageboxes, settingswindows in my application. I have a function showPopupDialog(const std::string& sourceQMLFile) which should handle this.
    My popup dialogs/messageboxes/... are all implemented in seperate qml files. They have a custom look and feel (Their root item is a Rectangle, not a Window or a Dialog).

    If I do:

    appContect->showPopupDialog("qrc///TestDialog.qml");
    

    with:

    void ApplicationContext::showPopupDialog(const std::string& sourceQMLFile)
    {
    	if(_engine)
    	{
    		QQuickWindow* itm = qobject_cast<QQuickWindow*>(_engine->rootObjects().value(0));
    		if(itm)
    		{
    			QQmlComponent component(_engine, QUrl(QString::fromStdString(sourceQMLFile)));
    			QObject* childItem = qobject_cast<QObject*>(component.create());
    			childItem->setParent(itm);
    		}
    	}	
    }
    

    and TestDialog.qml:

    import QtQuick 2.0
    
    Rectangle {
        width: 100;
    	height: 100;
    	color: "Red";
    	visible: true;
    }
    

    I don't see anything. If I change in the TestDialog.qml the Rectangle with a Dialog, it shows me a dialog, but I don't want to have the standard frame/framebuttons/title. What Am I doing wrong? How can I best load my custom dialogs/messageboxes? Or should I better use a dialog/window as a rootitem (but then i want to have it frameless)?
    Regards,

    Jan



  • Setting a (non-visual) parent object is not enough to make a QQuickItem visible. You must set a (visual) parent item. It can be the window's content item, or any other item that is in the window.

    QQuickItem* childItem = qobject_cast<QQuickItem*>(component.create());
    if (childItem)
        childItem->setParentItem(window->contentItem());
    


  • Changed the loading code to:

    void ApplicationContext::showPopupDialog(const std::string& source)
    {
    	if(_engine)
    	{
    		QQuickWindow* itm = qobject_cast<QQuickWindow*>(_engine->rootObjects().value(0));
    		if(itm)
    		{
    			QQmlComponent component(_engine, QUrl(QString::fromStdString(source)));
    			QObject* childItem = qobject_cast<QObject*>(component.create());
    			if(childItem)
    			{
    				childItem->setParent(itm->contentItem());
    			}			
    		}
    	}	
    }
    

    and the TestDialog.qml to

    import QtQuick 2.0
    
    Rectangle {
    	x: 0;
    	y: 0;
        width: 1000;
    	height: 1000;
    	color: "Red";
    	visible: true;
    
    	Component.onCompleted:
    	{
    		console.log("TestDialog loaded");
    	}
    }
    

    Maybe important info:
    My main.cpp:

    _engine = new QQmlApplicationEngine();
    ...
    _engine->load(QUrl(QStringLiteral("qrc:/MainWindow.qml")));
    

    and my MainWindow.qml

    import QtQuick 2.3
    import QtQuick.Controls 1.4
    import QtQuick.Layouts 1.2
    import QtQuick.Window 2.2
    
    Window
    {
    	id: mainWindow;
    
    	property var logo: "qrc:///logo.png";
    	property var applicationName: "Application";
    	property var projectName: "Untitled";
    
    	width: 800;
    	height: 600;
    	visible: false;
    
    	flags: Qt.FramelessWindowHint | Qt.WindowMinimizeButtonHint | Qt.WindowSystemMenuHint | Qt.Window;
    
    ...
    
    	Component.onCompleted: mainWindow.showMaximized();
    }
    
    

    But still nothing when I try to show the TestDialog (my console output shows qml: TestDialog loaded, so i assume the item is loaded correctly...). It's not because the QQmlComponent gets out of scope, right? (tried to change it to a pointer, but no difference).



  • You are still calling QObject::setParent() instead of QQuickItem::setParentItem().



  • Wow, I should read the answers more carefully. It works now, Thanks!

    Jan


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.