Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. [Solved] Cannot access custom widgets loaded by uiloader
QtWS25 Last Chance

[Solved] Cannot access custom widgets loaded by uiloader

Scheduled Pinned Locked Moved General and Desktop
10 Posts 3 Posters 3.7k Views
  • 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
    krrl
    wrote on last edited by
    #1

    i've created a designer plugin with custom widgets. I can use them in the Designer.
    During run-time i want to load these widgets. But even though i can see my widgets in the created gui, i cant get access to them programmatically...
    @
    QUiLoader loader;
    loader.addPluginPath("."); //copied the designer lib to the path
    qDebug() << loader.availableWidgets(); //recognizes custom widgets

    QWidget* gui = loader.load(new QFile&#40;"form.ui"&#41;&#41;;
    //FlipButton is a customWidget derived from QToolButton
    QList<FlipButton*> flips = gui->findChildren<FlipButton*>(); 
    qDebug() << flips.size(); // prints zero
    qDebug() << flips;
    

    @

    Loading standard qt widgets, works fine.
    Printing them via
    @
    qDebug() << gui->findChildren<QWidget*>();
    @
    Shows ... FlipButton(0x8a8aa80, name = "flipButton") ...
    in the output, which suggests that the right custom class is created in memory.

    But how can i access them?
    Any help is greatly appreciated.

    1 Reply Last reply
    0
    • K Offline
      K Offline
      krrl
      wrote on last edited by
      #2

      found a workaround.
      @
      QList<QWidget*> list = gui->findChildren<QWidget*>();
      foreach(QWidget* w, list)
      {
      customWidget* cw;
      if((cw=static_cast<customWidget*>(w)))
      //...
      }
      @

      alternatively use dynamic_cast or reinterpret_cast works
      aswell. Weird that qobject_cast always fails tho.
      Shrug

      1 Reply Last reply
      0
      • SGaistS Offline
        SGaistS Offline
        SGaist
        Lifetime Qt Champion
        wrote on last edited by
        #3

        Hi,

        If qobject_cast fails then there's something fishy going on. Can you provide a minimal compilable sample application that reproduce this behavior ?

        Also, which OS/Qt version are you running ?

        Interested in AI ? www.idiap.ch
        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

        1 Reply Last reply
        0
        • A Offline
          A Offline
          andreyc
          wrote on last edited by
          #4

          Thank you for sharing a solution.
          Do you have Q_OBJECT define in your class?

          [EDIT]: Checked QObject source. qobject_cast has an assert if Q_OBJECT is not included. My questions is answered :-)

          1 Reply Last reply
          0
          • K Offline
            K Offline
            krrl
            wrote on last edited by
            #5

            Im using Ubuntu 13.10 with Qt5.2.0 (32bit).
            I omitted the files mywidgetplugin.{h,cpp} mywidget.{h,cpp} for brevity. They were automatically created by wizard (new project->other project->qt custom designer widget)

            designer project file
            @
            CONFIG += plugin release
            TARGET = mywidgetplugin
            TEMPLATE = lib

            HEADERS = mywidgetplugin.h mywidget.h
            SOURCES = mywidgetplugin.cpp mywidget.cpp
            LIBS += -L.

            QT += designer

            target.path = /path/to/plugins/designer
            client.path = /path/to/client/
            client.files = libmywidgetplugin.so

            INSTALLS += target client
            @

            client project file
            @
            QT = core gui uitools widgets
            TARGET = untitled
            TEMPLATE = app

            INCLUDEPATH += /path/to/designerPluginProject
            VPATH += /path/to/designerPluginProject
            HEADERS += mywidget.h
            SOURCES += main.cpp
            @
            client main.cpp
            @
            #include <QApplication>
            #include <QDebug>
            #include <QUiLoader>
            #include <QFile>
            #include <QWidget>
            #include "mywidget.h"
            int main(int argc, char *argv[])
            {
            QApplication a(argc, argv);
            QUiLoader loader;
            loader.clearPluginPaths();
            loader.addPluginPath(".");
            if( !loader.availableWidgets().contains("myWidget") )
            qDebug() << "UiLoader did not read custom widgets library";

            QWidget* gui = loader.load(new QFile&#40;"form.ui"&#41;&#41;;
            gui->show();
            
            myWidget* mw = gui->findChild<myWidget*>();
            qDebug() << "Found a myWidget? " << (mw!=NULL);
            
            QList<myWidget*> mws = gui->findChildren<myWidget*>();
            qDebug() << "Found myWidgets? " << !mws.isEmpty();
            
            QWidget* qwidget = gui->findChild<QWidget*>();
            qDebug() << "Found qwidget? " << (qwidget!=NULL);
            qDebug() << "dynamic_cast to myWidget?" << (dynamic_cast<myWidget*>(qwidget)!=NULL);
            qDebug() << "qobject_cast to myWidget?" << (qobject_cast<myWidget*>(qwidget)!=NULL);
            
            qDebug() << "list childs : " << gui->findChildren<QWidget*>();
            return a.exec&#40;&#41;;
            

            }
            @

            form.ui
            @
            <?xml version="1.0" encoding="UTF-8"?>
            <ui version="4.0">
            <class>Form</class>
            <widget class="QWidget" name="Form">
            <property name="geometry">
            <rect>
            <x>0</x>
            <y>0</y>
            <width>402</width>
            <height>302</height>
            </rect>
            </property>
            <property name="windowTitle">
            <string>Form</string>
            </property>
            <layout class="QHBoxLayout" name="horizontalLayout">
            <item>
            <widget class="myWidget" name="myWidget"/>
            </item>
            </layout>
            </widget>
            <customwidgets>
            <customwidget>
            <class>myWidget</class>
            <extends>QWidget</extends>
            <header>mywidget.h</header>
            </customwidget>
            </customwidgets>
            <resources/>
            <connections/>
            </ui>
            @

            When running client it prints:
            @
            main-Found a myWidget? false
            main-Found myWidgets? false
            main-Found qwidget? true
            main-dynamic_cast to myWidget? true
            main-qobject_cast to myWidget? false
            main-list childs : (myWidget(0x863f438, name = "myWidget") )
            @

            Im also not sure why i need to add VPath in client.pro
            Thanks for helping :)

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

              Got it! Wasnt linking against the plugin. Thought Qt would do it automatically...

              client project file
              @
              //...
              INCLUDEPATH += /path/to/designerPluginProject
              LIBS += -L. -lmywidgetplugin
              @

              When running client it prints:
              @
              main-Found a myWidget? true
              main-Found myWidgets? true
              main-Found qwidget? true
              main-dynamic_cast to myWidget? true
              main-qobject_cast to myWidget? true
              main-list childs : (myWidget(0x94200f8, name = "myWidget") )
              @

              1 Reply Last reply
              0
              • SGaistS Offline
                SGaistS Offline
                SGaist
                Lifetime Qt Champion
                wrote on last edited by
                #7

                IIRC you should have two libraries, one containing your widget and the other that is the current designer plugin. So you link your project to the library and not the plugin and you can update the library without the need to recompile the plugin (unless e.g. you are adding new widgets)

                Interested in AI ? www.idiap.ch
                Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                1 Reply Last reply
                0
                • K Offline
                  K Offline
                  krrl
                  wrote on last edited by
                  #8

                  Let my try rephrase for understanding:

                  create designer plugin containing custom widgets

                  create shared/static library which also contains the widgets

                  link project against the second

                  The advantage of this approach:
                  I can change the implementation (.cpp) of my custom widgets in the second library as long as the interface (.h or public stuff + properties) does not change with having to touch the designer lib.
                  Object if wrong!

                  1 Reply Last reply
                  0
                  • SGaistS Offline
                    SGaistS Offline
                    SGaist
                    Lifetime Qt Champion
                    wrote on last edited by
                    #9

                    I object ! But you almost got it

                    Here is the right order:

                    Create library containing the widgets

                    Create designer plugin linking to that lib

                    Link project to the first

                    So you have only one lib containing the widgets

                    Interested in AI ? www.idiap.ch
                    Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                    1 Reply Last reply
                    0
                    • K Offline
                      K Offline
                      krrl
                      wrote on last edited by
                      #10

                      Ah, that makes sense!
                      Thank you :)

                      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