Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. QML working in QQuickView, but not in custom QQuickWindow
Forum Updated to NodeBB v4.3 + New Features

QML working in QQuickView, but not in custom QQuickWindow

Scheduled Pinned Locked Moved Solved QML and Qt Quick
6 Posts 2 Posters 2.8k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • K Offline
    K Offline
    kloffy
    wrote on last edited by
    #1

    My aim is to use QML for GUI on top of some custom rendering that I am doing in OpenGL. Before going into that, I thought it would be good to get a better understanding of QML. Therefore, I thought I might start by implementing my own version of QQuickView on top of QQuickWindow (slowly working my way deeper into the workings of QML). However, while doing so, I quickly ran into a problem with the following QML:

    import QtQuick 2.5
    import QtQuick.Controls 1.4
    
    Item {
    	anchors.fill: parent
    
    	ListModel {
    		id: fruitModel
    
    		ListElement {
    			title: "Apple"
    			page: "Banana"
    		}
    		ListElement {
    			title: "Orange"
    			page: "Banana"
    		}
    		ListElement {
    			title: "Banana"
    			page: "Banana"
    		}
    	}
    
    	ListView {
    		anchors.fill: parent
    		model: fruitModel
    		delegate: Rectangle{
    			width: parent.width; height: 80
    			color: "red"
    			Text {
    				anchors.fill: parent
    				color: "black"
    				text: title
    			}
    		}
    	}
    }
    

    This is a pretty simple scene that works perfectly well if I display it in a QQuickView. However, if I use my custom window, only the first list item is displayed. Can anybody point me towards what is missing in my QQuickWindow subclass to make this work?

    #! /usr/bin/python3
    
    import os
    import sys
    
    from PyQt5 import QtCore, QtGui, QtNetwork, QtQml, QtQuick, QtWidgets
    
    def application_path(*paths):
        return os.path.join(os.path.dirname(os.path.realpath(__file__)), *paths)
    
    class MainWindow(QtQuick.QQuickWindow):
        def __init__(self):
            super(MainWindow, self).__init__()
    
            self._engine = QtQml.QQmlEngine(self)
            if not self._engine.incubationController():
                self._engine.setIncubationController(self.incubationController())
            
            self._engine.quit.connect(QtWidgets.QApplication.instance().quit)
        
        def setSource(self, url):
            context = QtQml.QQmlContext(self._engine)
    
            component = QtQml.QQmlComponent(self._engine)
            component.loadUrl(url)
    
            if component.isError():
                logger.error(component.errorString())
                return
    
            obj = component.create(context)
    
            if component.isError():
                logger.error(component.errorString())
                return
    
            if isinstance(obj, QtQuick.QQuickItem):
                obj.setParentItem(self.contentItem())
                self._root = obj
    
    if __name__ == '__main__':
        app = QtWidgets.QApplication(sys.argv)
        
        #view = QtQuick.QQuickView()
        view = MainWindow() 
        view.setSource(QtCore.QUrl.fromLocalFile(application_path("main.qml")))
        view.resize(800, 600)
        view.show()
        
        sys.exit(app.exec_())
    
    p3c0P 1 Reply Last reply
    0
    • K kloffy

      My aim is to use QML for GUI on top of some custom rendering that I am doing in OpenGL. Before going into that, I thought it would be good to get a better understanding of QML. Therefore, I thought I might start by implementing my own version of QQuickView on top of QQuickWindow (slowly working my way deeper into the workings of QML). However, while doing so, I quickly ran into a problem with the following QML:

      import QtQuick 2.5
      import QtQuick.Controls 1.4
      
      Item {
      	anchors.fill: parent
      
      	ListModel {
      		id: fruitModel
      
      		ListElement {
      			title: "Apple"
      			page: "Banana"
      		}
      		ListElement {
      			title: "Orange"
      			page: "Banana"
      		}
      		ListElement {
      			title: "Banana"
      			page: "Banana"
      		}
      	}
      
      	ListView {
      		anchors.fill: parent
      		model: fruitModel
      		delegate: Rectangle{
      			width: parent.width; height: 80
      			color: "red"
      			Text {
      				anchors.fill: parent
      				color: "black"
      				text: title
      			}
      		}
      	}
      }
      

      This is a pretty simple scene that works perfectly well if I display it in a QQuickView. However, if I use my custom window, only the first list item is displayed. Can anybody point me towards what is missing in my QQuickWindow subclass to make this work?

      #! /usr/bin/python3
      
      import os
      import sys
      
      from PyQt5 import QtCore, QtGui, QtNetwork, QtQml, QtQuick, QtWidgets
      
      def application_path(*paths):
          return os.path.join(os.path.dirname(os.path.realpath(__file__)), *paths)
      
      class MainWindow(QtQuick.QQuickWindow):
          def __init__(self):
              super(MainWindow, self).__init__()
      
              self._engine = QtQml.QQmlEngine(self)
              if not self._engine.incubationController():
                  self._engine.setIncubationController(self.incubationController())
              
              self._engine.quit.connect(QtWidgets.QApplication.instance().quit)
          
          def setSource(self, url):
              context = QtQml.QQmlContext(self._engine)
      
              component = QtQml.QQmlComponent(self._engine)
              component.loadUrl(url)
      
              if component.isError():
                  logger.error(component.errorString())
                  return
      
              obj = component.create(context)
      
              if component.isError():
                  logger.error(component.errorString())
                  return
      
              if isinstance(obj, QtQuick.QQuickItem):
                  obj.setParentItem(self.contentItem())
                  self._root = obj
      
      if __name__ == '__main__':
          app = QtWidgets.QApplication(sys.argv)
          
          #view = QtQuick.QQuickView()
          view = MainWindow() 
          view.setSource(QtCore.QUrl.fromLocalFile(application_path("main.qml")))
          view.resize(800, 600)
          view.show()
          
          sys.exit(app.exec_())
      
      p3c0P Offline
      p3c0P Offline
      p3c0
      Moderators
      wrote on last edited by
      #2

      Hi @kloffy and Welcome,

      I'm not aware of PyQt so I'm not sure what is causing that problem in that case. But I replicated the same code using C++ and it worked as expected. All 3 items are shown. Following is what I tried:
      MainWindow.cpp

      MainWindow::MainWindow()
      {
          QQmlEngine *eng = new QQmlEngine(this);
          eng->setIncubationController(incubationController());
      
          QQmlContext *con = new QQmlContext(eng);
      
          QQmlComponent *comp = new QQmlComponent(eng);
          comp->loadUrl(QUrl("qrc:/main.qml"));
      
          QQuickItem *obj = qobject_cast<QQuickItem*>(comp->create(con));
          obj->setParentItem(contentItem());
      }
      

      main.cpp

      QGuiApplication app(argc, argv);
      
      MainWindow win;
      win.resize(800,600);
      win.show();
      
      return app.exec();
      

      157

      1 Reply Last reply
      1
      • K Offline
        K Offline
        kloffy
        wrote on last edited by
        #3

        Thank you for testing the code in C++, I should have probably tried that myself. Your response has led me towards a solution. It appears that the problem is indeed specific to PyQt5, and in particular I have a feeling it might be related to object lifetimes. Something might be getting destroyed before it should be, which has me a bit worried about the robustness of PyQt5 in general. I can make the example work by keeping a reference to the context in a member of MainWindow, i.e.:

        self._context = QtQml.QQmlContext(self._engine)
        

        I was under the impression that in Qt's ownership model, the QQmlContext would be kept alive by its parent the QQmlEngine. I am really puzzled by what is going on, but I suppose in order to get clarity I will have to consult the PyQt5 guys.

        1 Reply Last reply
        0
        • K Offline
          K Offline
          kloffy
          wrote on last edited by
          #4

          Oh, mea culpa to the PyQt5 guys. I just saw that the parent is passed as the second parameter to QQmlContext. If I pass QQmlEngine twice, it also works:

          context = QtQml.QQmlContext(self._engine, self._engine)
          

          On the other hand, in that case I am a bit confused as to why this is not an issue in C++.

          p3c0P 1 Reply Last reply
          0
          • K kloffy

            Oh, mea culpa to the PyQt5 guys. I just saw that the parent is passed as the second parameter to QQmlContext. If I pass QQmlEngine twice, it also works:

            context = QtQml.QQmlContext(self._engine, self._engine)
            

            On the other hand, in that case I am a bit confused as to why this is not an issue in C++.

            p3c0P Offline
            p3c0P Offline
            p3c0
            Moderators
            wrote on last edited by
            #5

            @kloffy I too have no idea about the implementation :) You can try asking it on the mailing lists.
            http://lists.qt-project.org/mailman/listinfo/interest
            http://lists.qt-project.org/mailman/listinfo
            The Qt developers might know the exact reason behind these internals.

            157

            1 Reply Last reply
            1
            • K Offline
              K Offline
              kloffy
              wrote on last edited by
              #6

              Thanks again, the mailing list will come in handy, no doubt. As far as the original problem goes, I think it can be considered resolved! :)

              1 Reply Last reply
              0

              • Login

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • Users
              • Groups
              • Search
              • Get Qt Extensions
              • Unsolved