跳到內容
  • 版面
  • 最新
  • 標籤
  • 熱門
  • 使用者
  • 群組
  • 搜尋
  • Get Qt Extensions
  • Unsolved
Collapse
品牌標誌
  1. 首頁
  2. Qt Development
  3. General and Desktop
  4. Where are the .ui files?
Forum Updated to NodeBB v4.3 + New Features

Where are the .ui files?

已排程 已置頂 已鎖定 已移動 Unsolved General and Desktop
21 貼文 8 Posters 1.5k 瀏覽 4 Watching
  • 從舊到新
  • 從新到舊
  • 最多點贊
回覆
  • 在新貼文中回覆
登入後回覆
此主題已被刪除。只有擁有主題管理權限的使用者可以查看。
  • G 離線
    G 離線
    garybollenbach
    寫於 最後由 編輯
    #1

    Hi All,
    Rank beginner here, hoping someone will take my super basic question. My QT 5.15 is on Linux at 4K, and, lucky me, I have all the example projects on the Welcome page, as well as a well-behaved and viewable interface with no need for environment switch. If I am counting right, there are 211 example projects, a veritable gold mine. Of these 211, I count only 15 projects which contain a .ui file, the rest containing only a .h file, or multiple, or neither. This I do not understand. Obviously you can make and build a project with only a .h file, but what about revision? How to revise a project with no .ui file, if the revision involves a change to the form?

    thanks
    Gary B

    Pl45m4P 1 條回覆 最後回覆
    0
    • Kent-DorfmanK 離線
      Kent-DorfmanK 離線
      Kent-Dorfman
      寫於 最後由 Kent-Dorfman 編輯
      #2

      A ui file is only relevant if you are using the designer program to create a gui interface. Some of the examples will manually create the interface using the widgets directly. Both are valid approaches to creating an app.

      1 條回覆 最後回覆
      3
      • SGaistS 離線
        SGaistS 離線
        SGaist
        Lifetime Qt Champion
        寫於 最後由 編輯
        #3

        Hi,

        It's in fact pretty simple: you don't need any UI files to build a Qt interface. It's a nice helper though.

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

        1 條回覆 最後回覆
        2
        • G garybollenbach

          Hi All,
          Rank beginner here, hoping someone will take my super basic question. My QT 5.15 is on Linux at 4K, and, lucky me, I have all the example projects on the Welcome page, as well as a well-behaved and viewable interface with no need for environment switch. If I am counting right, there are 211 example projects, a veritable gold mine. Of these 211, I count only 15 projects which contain a .ui file, the rest containing only a .h file, or multiple, or neither. This I do not understand. Obviously you can make and build a project with only a .h file, but what about revision? How to revise a project with no .ui file, if the revision involves a change to the form?

          thanks
          Gary B

          Pl45m4P 離線
          Pl45m4P 離線
          Pl45m4
          寫於 最後由 編輯
          #4

          @garybollenbach said in Where are the .ui files?:

          Obviously you can make and build a project with only a .h file, but what about revision?

          You need to look at the relevant C++ code and understand it.

          How to revise a project with no .ui file, if the revision involves a change to the form?

          Same here.
          Like @Kent-Dorfman and @SGaist have said... there is no need at all for *.ui files in a Qt project.
          It's nice to have, but the more professional it gets, projects tend not to have UI files.
          (easier to debug your own UI code than what UIC outputs and places in the generated header).

          Find the places where it addresses the GUI and make your changes.


          If debugging is the process of removing software bugs, then programming must be the process of putting them in.

          ~E. W. Dijkstra

          1 條回覆 最後回覆
          1
          • G 離線
            G 離線
            garybollenbach
            寫於 最後由 編輯
            #5

            Grateful thanks for responses. Unfortunately the lengthy scavenger hunt I did resulted in no joy. Apologies for my obtuseness, but if I go File > New File or Project > Other Project > Empty qmake Project > choose and finish, can someone give me the minimum required in files/code/exact filenames to show a main form? (Creator is 6.0.2.)

            jsulmJ 1 條回覆 最後回覆
            0
            • Kent-DorfmanK 離線
              Kent-DorfmanK 離線
              Kent-Dorfman
              寫於 最後由 編輯
              #6

              Not a main form, but will display a QLabel widget on screen. Changing it up to a main form is left as an exercise for the OP.

              At least in X11/posix a QWidget derived widget can be realized directly on the window manager display.

              #include <QApplication>
              #include <QLabel>
              
              int main(int argc, char* argv[]) {
                  auto theApp = new QApplication(argc,argv);
                  auto w = new QLabel("some text", null);
                  w->show();
                  return theApp->exec();
              }
              

              May be a syntax error or missing include but the above should be semantically correct pseudo-code and I'm too lazy to create .pro file and build it.
              LOL

              1 條回覆 最後回覆
              1
              • G garybollenbach

                Grateful thanks for responses. Unfortunately the lengthy scavenger hunt I did resulted in no joy. Apologies for my obtuseness, but if I go File > New File or Project > Other Project > Empty qmake Project > choose and finish, can someone give me the minimum required in files/code/exact filenames to show a main form? (Creator is 6.0.2.)

                jsulmJ 離線
                jsulmJ 離線
                jsulm
                Lifetime Qt Champion
                寫於 最後由 編輯
                #7

                @garybollenbach said in Where are the .ui files?:

                can someone give me the minimum required in files/code/exact filenames to show a main form? (Creator is 6.0.2.)

                You only need one cpp file, like main.cpp (the name of the file doesn't matter).
                And you need to add widgets modules in your pro file.
                You can see what exactly you need to add if you create a simple widgets application.

                https://forum.qt.io/topic/113070/qt-code-of-conduct

                1 條回覆 最後回覆
                2
                • S 離線
                  S 離線
                  SimonSchroeder
                  寫於 最後由 編輯
                  #8

                  Just to make sure this discussion is complete: There are 3 ways to create a GUI with Qt.

                  1. Use QtWidgets and write the C++ code yourself.
                  2. Use QtWidgets and the Designer to create a .ui file to be translated into C++ code.
                  3. Use QML instead of QtWidgets.

                  So, the main question is if you want to use QtWidgets or QML.

                  Minimal example:

                  #include <QApplication>
                  #include <QMainWindow>
                  
                  // class MainWindow should go in a separate header file with corresponding .cpp file.
                  class MainWindow : public QMainWindow
                  {
                  public:
                      MainWindow(QWidget *parent = nullptr) : QMainWindow(parent) 
                      {
                          // you might want to create more subwidgets or menues in here -> rather put the implementation in .cpp
                      }
                  };
                  
                  int main(int argc, char *argv[])
                  {
                      QApplication app(argc,argv);
                      MainWindow w; // prefer to use regular variables instead of pointers inside the main function
                      w.show();
                      return app.exec();
                  }
                  

                  You can also create a MainWindow UI with Qt Designer. Then you need to get the corresponding ui from the generated header file inside your MainWindow.

                  This is mostly the same as @Kent-Dorfman, but I certainly would advise not to use pointers in main.

                  Even in very complex programs the main function should not be more complicated than this. In a GUI application most actions are triggered by the user and thus this part of MainWindow and its subwidgets.

                  Kent-DorfmanK 1 條回覆 最後回覆
                  1
                  • S SimonSchroeder

                    Just to make sure this discussion is complete: There are 3 ways to create a GUI with Qt.

                    1. Use QtWidgets and write the C++ code yourself.
                    2. Use QtWidgets and the Designer to create a .ui file to be translated into C++ code.
                    3. Use QML instead of QtWidgets.

                    So, the main question is if you want to use QtWidgets or QML.

                    Minimal example:

                    #include <QApplication>
                    #include <QMainWindow>
                    
                    // class MainWindow should go in a separate header file with corresponding .cpp file.
                    class MainWindow : public QMainWindow
                    {
                    public:
                        MainWindow(QWidget *parent = nullptr) : QMainWindow(parent) 
                        {
                            // you might want to create more subwidgets or menues in here -> rather put the implementation in .cpp
                        }
                    };
                    
                    int main(int argc, char *argv[])
                    {
                        QApplication app(argc,argv);
                        MainWindow w; // prefer to use regular variables instead of pointers inside the main function
                        w.show();
                        return app.exec();
                    }
                    

                    You can also create a MainWindow UI with Qt Designer. Then you need to get the corresponding ui from the generated header file inside your MainWindow.

                    This is mostly the same as @Kent-Dorfman, but I certainly would advise not to use pointers in main.

                    Even in very complex programs the main function should not be more complicated than this. In a GUI application most actions are triggered by the user and thus this part of MainWindow and its subwidgets.

                    Kent-DorfmanK 離線
                    Kent-DorfmanK 離線
                    Kent-Dorfman
                    寫於 最後由 編輯
                    #9

                    @SimonSchroeder said in Where are the .ui files?:

                    This is mostly the same as @Kent-Dorfman, but I certainly would advise not to use pointers in main.

                    So convince me why stack allocated MainWindow or QApplication object is superior to one allocated on the heap. The argument comes across as somewhat "stylesque" and if it's really a bad idea then please explain your reasoning.

                    jsulmJ 1 條回覆 最後回覆
                    0
                    • Kent-DorfmanK Kent-Dorfman

                      @SimonSchroeder said in Where are the .ui files?:

                      This is mostly the same as @Kent-Dorfman, but I certainly would advise not to use pointers in main.

                      So convince me why stack allocated MainWindow or QApplication object is superior to one allocated on the heap. The argument comes across as somewhat "stylesque" and if it's really a bad idea then please explain your reasoning.

                      jsulmJ 離線
                      jsulmJ 離線
                      jsulm
                      Lifetime Qt Champion
                      寫於 最後由 編輯
                      #10

                      @Kent-Dorfman Not a real issue in this case, but you're leaking memory (will be freed anyway when the app is closing). Also stack allocation is faster than heap allocation. And why would you actually do heap allocation in this case?

                      https://forum.qt.io/topic/113070/qt-code-of-conduct

                      1 條回覆 最後回覆
                      1
                      • Kent-DorfmanK 離線
                        Kent-DorfmanK 離線
                        Kent-Dorfman
                        寫於 最後由 編輯
                        #11

                        @jsulm Admittedly, I don't know as much about qt6, but have background from qt3-qt5...and the concept of heap managed QObjects is intrinsic in the framework for those versions and for good reason. The transfer of object ownership in the parent child widget tree relies on it, and is why stack allocated QObjects are a bad idea. They can end up double-deleted if they are "linked" to a widget tree. I know that there is an argument that since main() is top level, anything created under main will be destroyed before main is...but!!!!

                        I content that we should treat main(), and objects created in main, just as objects created in any other function with regard to the framework...the key here being consistency, rather than (in this case) necessity.

                        As far as efficiency of heap vs stack, lets keep it in perspective. A few extra cycles to allocate a top level widget is negligible in the grand scheme.

                        In my previous I took Schroeder to infer that main is (by necessity) suppose to be as small and trivial as possible, and I think I was trying to disarm that position as being more stylistic than code-quality oriented.

                        S 1 條回覆 最後回覆
                        1
                        • JonBJ 線上
                          JonBJ 線上
                          JonB
                          寫於 最後由 JonB 編輯
                          #12

                          I am going to (take the plunge and) chime in on this one :) In defence of @Kent-Dorfman . IMHO (and only in my humble opinion) some C++ers here are "overly" keen in insisting on stack allocation whenever possible.

                          I started Qt with Python (not my fault, that's what the stakeholder was using!). There we do not even have this debate, as all allocations are heap. And it works just fine. So it is perfectly possible to write Qt code with no stack allocations. In theory at least Qt is just as supported from Python as from C++, so why insist on a C++-only language feature?

                          It is true that with heap allocation you have to track lifetime carefully, you must make sure you do not access after deallocated and yet you should not fail to deallocate. But there are equally nasty "gotchas" with stack allocation. How many times do we look at people's code here and say "your error is that you have allowed a stack allocated object to go out of scope while still using the object elsewhere"? Not to mention:

                          QObject foo;
                          QObject bar;
                          foo.setParent(&bar);
                          

                          Wait till that goes out of scope....

                          As far as "stack allocation is faster than heap allocation" is concerned, surely this is miniscule compared with the code which executes from the constructor of QObject or QWidget.

                          I do think this is just a "stylistic" thing. The majority of one's code will be full of heap rather than stack allocated objects. uic generates code for all objects to be allocated on the heap. I do usually allocate on the stack rather than heap from my C++ code where it is suitable but I really don't think this is a big issue.

                          1 條回覆 最後回覆
                          2
                          • J.HilkJ 線上
                            J.HilkJ 線上
                            J.Hilk
                            Moderators
                            寫於 最後由 J.Hilk 編輯
                            #13

                            Don't stress heap vs stack too much, It's Qt we're talking about. Every QObject does heap allocation, wether you allocate it on the stack or not:

                            static int cntNew{0};
                            
                            void* operator new(std::size_t size) {
                                std::cout << "Operator new called: " << size << " Bytes\n";
                                void* ptr = std::malloc(size);
                                if (!ptr) {
                                    throw std::bad_alloc();
                                }
                                cntNew++;
                                return ptr;
                            }
                            
                            void operator delete(void* ptr) noexcept {
                                std::cout << "Operator delete called\n";
                                std::free(ptr);
                            }
                            
                            
                            int main(int argc, char *argv[])
                            {
                                std::cout << "Main entry" << "\n";
                               // QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
                               QCoreApplication app(argc, argv);
                               std::cout << "\n" <<  "After QCoreApplication " << "calls to new: " << cntNew << "\n";
                            
                               cntNew = 0;
                               std::cout << "stack allocated begin" << "\n";
                               QObject stackObj;
                               std::cout << "\n" << "heap allocated end! Calls to new: " << cntNew << "\n";
                            
                               cntNew = 0;
                               std::cout << "stack allocated begin" << "\n";
                               QObject *heapObj{new QObject()};
                               std::cout << "\n" << "heap allocated end! Calls to new: " << cntNew << "\n";
                            
                               delete heapObj;
                            
                               return 0;
                            }
                            
                            Operator new called: 8 Bytes
                            Operator new called: 48 Bytes
                            Operator new called: 16 Bytes
                            Operator new called: 528 Bytes
                            Operator new called: 104 Bytes
                            Operator new called: 240 Bytes
                            Operator new called: 80 Bytes
                            Operator new called: 88 Bytes
                            Operator new called: 96 Bytes
                            Operator new called: 88 Bytes
                            Operator new called: 176 Bytes
                            Operator delete called
                            Operator new called: 72 Bytes
                            Operator new called: 8 Bytes
                            Operator new called: 64 Bytes
                            Operator new called: 72 Bytes
                            Operator new called: 64 Bytes
                            Operator new called: 16 Bytes
                            Operator delete called
                            Operator delete called
                            Operator new called: 40 Bytes
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator new called: 104 Bytes
                            Operator new called: 104 Bytes
                            Operator delete called
                            Operator delete called
                            Operator new called: 104 Bytes
                            Operator new called: 104 Bytes
                            Operator delete called
                            Operator delete called
                            Operator new called: 104 Bytes
                            Operator new called: 72 Bytes
                            Operator new called: 104 Bytes
                            Operator new called: 104 Bytes
                            Operator delete called
                            Operator new called: 80 Bytes
                            Operator delete called
                            Operator new called: 104 Bytes
                            Operator delete called
                            Operator new called: 112 Bytes
                            Operator new called: 40 Bytes
                            Operator delete called
                            Operator delete called
                            Operator new called: 48 Bytes
                            Operator new called: 40 Bytes
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator new called: 112 Bytes
                            Operator delete called
                            Operator new called: 88 Bytes
                            Operator new called: 104 Bytes
                            Operator delete called
                            Operator new called: 104 Bytes
                            Operator new called: 208 Bytes
                            Operator delete called
                            Operator delete called
                            Operator new called: 32 Bytes
                            Operator delete called
                            Operator new called: 56 Bytes
                            Operator new called: 56 Bytes
                            Operator new called: 80 Bytes
                            Operator new called: 72 Bytes
                            Operator new called: 72 Bytes
                            Operator new called: 72 Bytes
                            Operator delete called
                            Operator new called: 40 Bytes
                            Operator new called: 40 Bytes
                            Operator new called: 64 Bytes
                            Operator new called: 64 Bytes
                            Operator new called: 64 Bytes
                            Operator new called: 64 Bytes
                            Operator new called: 16 Bytes
                            Operator new called: 16 Bytes
                            Operator new called: 16 Bytes
                            Operator new called: 16 Bytes
                            Operator new called: 16 Bytes
                            Operator new called: 16 Bytes
                            Operator new called: 16 Bytes
                            Operator new called: 16 Bytes
                            Operator new called: 16 Bytes
                            Operator new called: 16 Bytes
                            Operator new called: 16 Bytes
                            Operator new called: 16 Bytes
                            Operator new called: 16 Bytes
                            Operator new called: 16 Bytes
                            Operator new called: 16 Bytes
                            Operator new called: 16 Bytes
                            Operator new called: 16 Bytes
                            Operator new called: 16 Bytes
                            Operator new called: 16 Bytes
                            Operator new called: 56 Bytes
                            Operator new called: 56 Bytes
                            Operator new called: 56 Bytes
                            Operator new called: 72 Bytes
                            Operator new called: 16 Bytes
                            Operator new called: 64 Bytes
                            Operator new called: 64 Bytes
                            Operator new called: 64 Bytes
                            Operator new called: 64 Bytes
                            Operator new called: 64 Bytes
                            Operator new called: 64 Bytes
                            Operator new called: 64 Bytes
                            Operator new called: 64 Bytes
                            Operator new called: 64 Bytes
                            Operator new called: 64 Bytes
                            Operator new called: 64 Bytes
                            Operator new called: 64 Bytes
                            Operator new called: 64 Bytes
                            Operator new called: 64 Bytes
                            Operator new called: 64 Bytes
                            Operator new called: 64 Bytes
                            Operator new called: 64 Bytes
                            Operator new called: 64 Bytes
                            Operator new called: 64 Bytes
                            Operator new called: 64 Bytes
                            Operator new called: 64 Bytes
                            Operator new called: 64 Bytes
                            Operator new called: 64 Bytes
                            Operator new called: 64 Bytes
                            Operator new called: 64 Bytes
                            Operator new called: 64 Bytes
                            Operator new called: 64 Bytes
                            Operator new called: 64 Bytes
                            Operator new called: 64 Bytes
                            Operator new called: 64 Bytes
                            Operator new called: 56 Bytes
                            Operator new called: 16 Bytes
                            Operator new called: 4 Bytes
                            Operator new called: 264 Bytes
                            Operator new called: 8 Bytes
                            Operator delete called
                            Operator new called: 16 Bytes
                            Operator delete called
                            Operator new called: 32 Bytes
                            Operator delete called
                            Operator new called: 64 Bytes
                            Operator delete called
                            Operator new called: 56 Bytes
                            Operator new called: 16 Bytes
                            Operator new called: 8 Bytes
                            Operator new called: 56 Bytes
                            Operator new called: 16 Bytes
                            Operator new called: 16 Bytes
                            Operator delete called
                            Operator new called: 128 Bytes
                            Operator delete called
                            Operator new called: 256 Bytes
                            Operator delete called
                            Operator new called: 56 Bytes
                            Operator new called: 16 Bytes
                            Operator new called: 32 Bytes
                            Operator new called: 48 Bytes
                            Operator delete called
                            Operator new called: 32 Bytes
                            Operator delete called
                            Operator new called: 32 Bytes
                            Operator new called: 56 Bytes
                            Operator new called: 16 Bytes
                            Operator new called: 56 Bytes
                            Operator new called: 16 Bytes
                            Operator new called: 64 Bytes
                            Operator delete called
                            Operator delete called
                            Operator new called: 56 Bytes
                            Operator new called: 16 Bytes
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator new called: 80 Bytes
                            Operator new called: 104 Bytes
                            Operator delete called
                            Operator delete called
                            Operator new called: 112 Bytes
                            Operator delete called
                            Operator new called: 104 Bytes
                            Operator new called: 208 Bytes
                            Operator delete called
                            Operator delete called
                            Operator new called: 112 Bytes
                            Operator delete called
                            Operator new called: 104 Bytes
                            Operator new called: 208 Bytes
                            Operator delete called
                            Operator delete called
                            Operator new called: 112 Bytes
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator new called: 120 Bytes
                            Operator new called: 40 Bytes
                            Operator new called: 40 Bytes
                            Operator new called: 40 Bytes
                            Operator new called: 152 Bytes
                            Operator new called: 384 Bytes
                            Operator new called: 40 Bytes
                            Operator new called: 152 Bytes
                            Operator new called: 384 Bytes
                            Operator new called: 40 Bytes
                            Operator new called: 152 Bytes
                            Operator new called: 384 Bytes
                            Operator new called: 40 Bytes
                            Operator new called: 152 Bytes
                            Operator new called: 384 Bytes
                            Operator new called: 640 Bytes
                            Operator delete called
                            Operator new called: 40 Bytes
                            Main entry
                            Operator new called: 240 Bytes
                            Operator new called: 152 Bytes
                            Operator new called: 16 Bytes
                            Operator new called: 200 Bytes
                            Operator new called: 120 Bytes
                            Operator new called: 128 Bytes
                            Operator new called: 16 Bytes
                            Operator new called: 264 Bytes
                            Operator new called: 144 Bytes
                            Operator new called: 32 Bytes
                            Operator delete called
                            Operator new called: 32 Bytes
                            Operator delete called
                            Operator new called: 488 Bytes
                            Operator delete called
                            Operator new called: 24 Bytes
                            Operator new called: 488 Bytes
                            Operator delete called
                            Operator new called: 280 Bytes
                            Operator delete called
                            Operator new called: 448 Bytes
                            Operator new called: 16 Bytes
                            Operator new called: 200 Bytes
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator new called: 488 Bytes
                            Operator delete called
                            Operator new called: 40 Bytes
                            Operator new called: 152 Bytes
                            Operator new called: 768 Bytes
                            
                            After QCoreApplication calls to new: 181
                            stack allocated begin
                            Operator new called: 120 Bytes
                            
                            heap allocated end! Calls to new: 1
                            stack allocated begin
                            Operator new called: 16 Bytes
                            Operator new called: 120 Bytes
                            
                            heap allocated end! Calls to new: 2
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            Operator delete called
                            

                            => 181 calls to new after QCoreApplication is created, 1 call to new for the stack QObject, 2 calls to new for the heap QObject


                            Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                            Q: What's that?
                            A: It's blue light.
                            Q: What does it do?
                            A: It turns blue.

                            Kent-DorfmanK 1 條回覆 最後回覆
                            3
                            • J.HilkJ J.Hilk

                              Don't stress heap vs stack too much, It's Qt we're talking about. Every QObject does heap allocation, wether you allocate it on the stack or not:

                              static int cntNew{0};
                              
                              void* operator new(std::size_t size) {
                                  std::cout << "Operator new called: " << size << " Bytes\n";
                                  void* ptr = std::malloc(size);
                                  if (!ptr) {
                                      throw std::bad_alloc();
                                  }
                                  cntNew++;
                                  return ptr;
                              }
                              
                              void operator delete(void* ptr) noexcept {
                                  std::cout << "Operator delete called\n";
                                  std::free(ptr);
                              }
                              
                              
                              int main(int argc, char *argv[])
                              {
                                  std::cout << "Main entry" << "\n";
                                 // QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
                                 QCoreApplication app(argc, argv);
                                 std::cout << "\n" <<  "After QCoreApplication " << "calls to new: " << cntNew << "\n";
                              
                                 cntNew = 0;
                                 std::cout << "stack allocated begin" << "\n";
                                 QObject stackObj;
                                 std::cout << "\n" << "heap allocated end! Calls to new: " << cntNew << "\n";
                              
                                 cntNew = 0;
                                 std::cout << "stack allocated begin" << "\n";
                                 QObject *heapObj{new QObject()};
                                 std::cout << "\n" << "heap allocated end! Calls to new: " << cntNew << "\n";
                              
                                 delete heapObj;
                              
                                 return 0;
                              }
                              
                              Operator new called: 8 Bytes
                              Operator new called: 48 Bytes
                              Operator new called: 16 Bytes
                              Operator new called: 528 Bytes
                              Operator new called: 104 Bytes
                              Operator new called: 240 Bytes
                              Operator new called: 80 Bytes
                              Operator new called: 88 Bytes
                              Operator new called: 96 Bytes
                              Operator new called: 88 Bytes
                              Operator new called: 176 Bytes
                              Operator delete called
                              Operator new called: 72 Bytes
                              Operator new called: 8 Bytes
                              Operator new called: 64 Bytes
                              Operator new called: 72 Bytes
                              Operator new called: 64 Bytes
                              Operator new called: 16 Bytes
                              Operator delete called
                              Operator delete called
                              Operator new called: 40 Bytes
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator new called: 104 Bytes
                              Operator new called: 104 Bytes
                              Operator delete called
                              Operator delete called
                              Operator new called: 104 Bytes
                              Operator new called: 104 Bytes
                              Operator delete called
                              Operator delete called
                              Operator new called: 104 Bytes
                              Operator new called: 72 Bytes
                              Operator new called: 104 Bytes
                              Operator new called: 104 Bytes
                              Operator delete called
                              Operator new called: 80 Bytes
                              Operator delete called
                              Operator new called: 104 Bytes
                              Operator delete called
                              Operator new called: 112 Bytes
                              Operator new called: 40 Bytes
                              Operator delete called
                              Operator delete called
                              Operator new called: 48 Bytes
                              Operator new called: 40 Bytes
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator new called: 112 Bytes
                              Operator delete called
                              Operator new called: 88 Bytes
                              Operator new called: 104 Bytes
                              Operator delete called
                              Operator new called: 104 Bytes
                              Operator new called: 208 Bytes
                              Operator delete called
                              Operator delete called
                              Operator new called: 32 Bytes
                              Operator delete called
                              Operator new called: 56 Bytes
                              Operator new called: 56 Bytes
                              Operator new called: 80 Bytes
                              Operator new called: 72 Bytes
                              Operator new called: 72 Bytes
                              Operator new called: 72 Bytes
                              Operator delete called
                              Operator new called: 40 Bytes
                              Operator new called: 40 Bytes
                              Operator new called: 64 Bytes
                              Operator new called: 64 Bytes
                              Operator new called: 64 Bytes
                              Operator new called: 64 Bytes
                              Operator new called: 16 Bytes
                              Operator new called: 16 Bytes
                              Operator new called: 16 Bytes
                              Operator new called: 16 Bytes
                              Operator new called: 16 Bytes
                              Operator new called: 16 Bytes
                              Operator new called: 16 Bytes
                              Operator new called: 16 Bytes
                              Operator new called: 16 Bytes
                              Operator new called: 16 Bytes
                              Operator new called: 16 Bytes
                              Operator new called: 16 Bytes
                              Operator new called: 16 Bytes
                              Operator new called: 16 Bytes
                              Operator new called: 16 Bytes
                              Operator new called: 16 Bytes
                              Operator new called: 16 Bytes
                              Operator new called: 16 Bytes
                              Operator new called: 16 Bytes
                              Operator new called: 56 Bytes
                              Operator new called: 56 Bytes
                              Operator new called: 56 Bytes
                              Operator new called: 72 Bytes
                              Operator new called: 16 Bytes
                              Operator new called: 64 Bytes
                              Operator new called: 64 Bytes
                              Operator new called: 64 Bytes
                              Operator new called: 64 Bytes
                              Operator new called: 64 Bytes
                              Operator new called: 64 Bytes
                              Operator new called: 64 Bytes
                              Operator new called: 64 Bytes
                              Operator new called: 64 Bytes
                              Operator new called: 64 Bytes
                              Operator new called: 64 Bytes
                              Operator new called: 64 Bytes
                              Operator new called: 64 Bytes
                              Operator new called: 64 Bytes
                              Operator new called: 64 Bytes
                              Operator new called: 64 Bytes
                              Operator new called: 64 Bytes
                              Operator new called: 64 Bytes
                              Operator new called: 64 Bytes
                              Operator new called: 64 Bytes
                              Operator new called: 64 Bytes
                              Operator new called: 64 Bytes
                              Operator new called: 64 Bytes
                              Operator new called: 64 Bytes
                              Operator new called: 64 Bytes
                              Operator new called: 64 Bytes
                              Operator new called: 64 Bytes
                              Operator new called: 64 Bytes
                              Operator new called: 64 Bytes
                              Operator new called: 64 Bytes
                              Operator new called: 56 Bytes
                              Operator new called: 16 Bytes
                              Operator new called: 4 Bytes
                              Operator new called: 264 Bytes
                              Operator new called: 8 Bytes
                              Operator delete called
                              Operator new called: 16 Bytes
                              Operator delete called
                              Operator new called: 32 Bytes
                              Operator delete called
                              Operator new called: 64 Bytes
                              Operator delete called
                              Operator new called: 56 Bytes
                              Operator new called: 16 Bytes
                              Operator new called: 8 Bytes
                              Operator new called: 56 Bytes
                              Operator new called: 16 Bytes
                              Operator new called: 16 Bytes
                              Operator delete called
                              Operator new called: 128 Bytes
                              Operator delete called
                              Operator new called: 256 Bytes
                              Operator delete called
                              Operator new called: 56 Bytes
                              Operator new called: 16 Bytes
                              Operator new called: 32 Bytes
                              Operator new called: 48 Bytes
                              Operator delete called
                              Operator new called: 32 Bytes
                              Operator delete called
                              Operator new called: 32 Bytes
                              Operator new called: 56 Bytes
                              Operator new called: 16 Bytes
                              Operator new called: 56 Bytes
                              Operator new called: 16 Bytes
                              Operator new called: 64 Bytes
                              Operator delete called
                              Operator delete called
                              Operator new called: 56 Bytes
                              Operator new called: 16 Bytes
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator new called: 80 Bytes
                              Operator new called: 104 Bytes
                              Operator delete called
                              Operator delete called
                              Operator new called: 112 Bytes
                              Operator delete called
                              Operator new called: 104 Bytes
                              Operator new called: 208 Bytes
                              Operator delete called
                              Operator delete called
                              Operator new called: 112 Bytes
                              Operator delete called
                              Operator new called: 104 Bytes
                              Operator new called: 208 Bytes
                              Operator delete called
                              Operator delete called
                              Operator new called: 112 Bytes
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator new called: 120 Bytes
                              Operator new called: 40 Bytes
                              Operator new called: 40 Bytes
                              Operator new called: 40 Bytes
                              Operator new called: 152 Bytes
                              Operator new called: 384 Bytes
                              Operator new called: 40 Bytes
                              Operator new called: 152 Bytes
                              Operator new called: 384 Bytes
                              Operator new called: 40 Bytes
                              Operator new called: 152 Bytes
                              Operator new called: 384 Bytes
                              Operator new called: 40 Bytes
                              Operator new called: 152 Bytes
                              Operator new called: 384 Bytes
                              Operator new called: 640 Bytes
                              Operator delete called
                              Operator new called: 40 Bytes
                              Main entry
                              Operator new called: 240 Bytes
                              Operator new called: 152 Bytes
                              Operator new called: 16 Bytes
                              Operator new called: 200 Bytes
                              Operator new called: 120 Bytes
                              Operator new called: 128 Bytes
                              Operator new called: 16 Bytes
                              Operator new called: 264 Bytes
                              Operator new called: 144 Bytes
                              Operator new called: 32 Bytes
                              Operator delete called
                              Operator new called: 32 Bytes
                              Operator delete called
                              Operator new called: 488 Bytes
                              Operator delete called
                              Operator new called: 24 Bytes
                              Operator new called: 488 Bytes
                              Operator delete called
                              Operator new called: 280 Bytes
                              Operator delete called
                              Operator new called: 448 Bytes
                              Operator new called: 16 Bytes
                              Operator new called: 200 Bytes
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator new called: 488 Bytes
                              Operator delete called
                              Operator new called: 40 Bytes
                              Operator new called: 152 Bytes
                              Operator new called: 768 Bytes
                              
                              After QCoreApplication calls to new: 181
                              stack allocated begin
                              Operator new called: 120 Bytes
                              
                              heap allocated end! Calls to new: 1
                              stack allocated begin
                              Operator new called: 16 Bytes
                              Operator new called: 120 Bytes
                              
                              heap allocated end! Calls to new: 2
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              Operator delete called
                              

                              => 181 calls to new after QCoreApplication is created, 1 call to new for the stack QObject, 2 calls to new for the heap QObject

                              Kent-DorfmanK 離線
                              Kent-DorfmanK 離線
                              Kent-Dorfman
                              寫於 最後由 編輯
                              #14

                              @J.Hilk said in Where are the .ui files?:

                              Don't stress heap vs stack too much, It's Qt we're talking about. Every QObject does heap allocation, wether you allocate it on the stack or not:

                              wellll.....there is a difference between "does heap allocation" and "is allocated on the stack". Kind of like the old c++ "is a" vs "has a" description of inheritance. Regardless of whether it's Qt or plain ole c++, if I allocate ANY object locally within a function then the data struct{} that makes it up will occupy the stack, and "maybe" the object has members that are heap allocated. This is where the problem of heap vs stack comes in for Qt objects.

                              If object ownership is transfered based on the widget parent child relationship, then when the locally allocated object goes out of scope in the function where it is defined then its destructor will be executed and risks corrupting the widget tree.

                              Where is the fault with that argument?

                              J.HilkJ 1 條回覆 最後回覆
                              0
                              • Kent-DorfmanK Kent-Dorfman

                                @J.Hilk said in Where are the .ui files?:

                                Don't stress heap vs stack too much, It's Qt we're talking about. Every QObject does heap allocation, wether you allocate it on the stack or not:

                                wellll.....there is a difference between "does heap allocation" and "is allocated on the stack". Kind of like the old c++ "is a" vs "has a" description of inheritance. Regardless of whether it's Qt or plain ole c++, if I allocate ANY object locally within a function then the data struct{} that makes it up will occupy the stack, and "maybe" the object has members that are heap allocated. This is where the problem of heap vs stack comes in for Qt objects.

                                If object ownership is transfered based on the widget parent child relationship, then when the locally allocated object goes out of scope in the function where it is defined then its destructor will be executed and risks corrupting the widget tree.

                                Where is the fault with that argument?

                                J.HilkJ 線上
                                J.HilkJ 線上
                                J.Hilk
                                Moderators
                                寫於 最後由 編輯
                                #15

                                @Kent-Dorfman no fault, really.

                                Personally the whole silent parent switching/assigning a bunch of QWidget/QWidgetreleated objects do, never set well with me. And it has been a source of bizarre errors in my past.

                                @JonB said in Where are the .ui files?:

                                How many times do we look at people's code here and say "your error is that you have allowed a stack allocated object to go out of scope while still using the object elsewhere"?

                                that is almost always because the person dereferenced a stack variable because a function explicitly expects a pointer. At which point all kinds of alarm bells should be start running in your head.

                                Too bad, -Wstack-address-passing is not a thing. :(


                                Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                                Q: What's that?
                                A: It's blue light.
                                Q: What does it do?
                                A: It turns blue.

                                1 條回覆 最後回覆
                                1
                                • Pl45m4P 離線
                                  Pl45m4P 離線
                                  Pl45m4
                                  寫於 最後由 Pl45m4 編輯
                                  #16

                                  To add to the discussion:
                                  Isn't it better in general to only allocate on the heap where it is beneficial or necessary?!
                                  Allocation time, scope, way of access, use case etc etc...

                                  But yeah, especially in your main function, you are leaking (if!) only as long as the program runs... and if you have some kind of game/application loop in your program (most main's do), objects allocated before that (here: app->exec() ) are alive until the end anyway, unless you delete/destroy them intentionally and manually.

                                  I think, as long as you understand the difference, both ways are fine...
                                  Have seen beginners creating everything, Qt and non-Qt related stuff, on the heap regardless... that could need some optimization :)


                                  If debugging is the process of removing software bugs, then programming must be the process of putting them in.

                                  ~E. W. Dijkstra

                                  Kent-DorfmanK 1 條回覆 最後回覆
                                  0
                                  • Pl45m4P Pl45m4

                                    To add to the discussion:
                                    Isn't it better in general to only allocate on the heap where it is beneficial or necessary?!
                                    Allocation time, scope, way of access, use case etc etc...

                                    But yeah, especially in your main function, you are leaking (if!) only as long as the program runs... and if you have some kind of game/application loop in your program (most main's do), objects allocated before that (here: app->exec() ) are alive until the end anyway, unless you delete/destroy them intentionally and manually.

                                    I think, as long as you understand the difference, both ways are fine...
                                    Have seen beginners creating everything, Qt and non-Qt related stuff, on the heap regardless... that could need some optimization :)

                                    Kent-DorfmanK 離線
                                    Kent-DorfmanK 離線
                                    Kent-Dorfman
                                    寫於 最後由 編輯
                                    #17

                                    @Pl45m4 said in Where are the .ui files?:

                                    Isn't it better in general to only allocate on the heap where it is beneficial or necessary?!
                                    Allocation time, scope, way of access, use case etc etc...

                                    In general c++, yes. In Qt, no. because of the whole widget tree ownership boondoggle.

                                    Pl45m4P 1 條回覆 最後回覆
                                    2
                                    • Kent-DorfmanK Kent-Dorfman

                                      @Pl45m4 said in Where are the .ui files?:

                                      Isn't it better in general to only allocate on the heap where it is beneficial or necessary?!
                                      Allocation time, scope, way of access, use case etc etc...

                                      In general c++, yes. In Qt, no. because of the whole widget tree ownership boondoggle.

                                      Pl45m4P 離線
                                      Pl45m4P 離線
                                      Pl45m4
                                      寫於 最後由 Pl45m4 編輯
                                      #18

                                      @Kent-Dorfman said in Where are the .ui files?:

                                      because of the whole widget tree ownership boondoggle.

                                      Haha :)

                                      Yes, and since QObject performs internal heap allocations anyway as @J.Hilk pointed out above, you can't even make that argument (-> keep it clean, reduce heap allocs... etc)

                                      I still do tho, for the good habits.


                                      If debugging is the process of removing software bugs, then programming must be the process of putting them in.

                                      ~E. W. Dijkstra

                                      1 條回覆 最後回覆
                                      0
                                      • SGaistS 離線
                                        SGaistS 離線
                                        SGaist
                                        Lifetime Qt Champion
                                        寫於 最後由 編輯
                                        #19

                                        Even if the runtime is supposed to free things, etc.
                                        It's still a good habit to destroy things properly in order for all the required cleanup to happen in a controlled fashion.
                                        If you take all Qt examples, main.cpp contains usually stack allocated QApplication (or one of its sibling) and a stack allocated "main" widget. The rest is usually heap allocated as should be if there's something more. This guarantees proper lifetime management. If you really want to use only pointers, a cleaner approach would be to use QScopedPointer for the app object and the main widget cited just before.
                                        Note that the same pattern applies when checking the C++ boilerplate used to start a QML based application.

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

                                        1 條回覆 最後回覆
                                        2
                                        • Kent-DorfmanK Kent-Dorfman

                                          @jsulm Admittedly, I don't know as much about qt6, but have background from qt3-qt5...and the concept of heap managed QObjects is intrinsic in the framework for those versions and for good reason. The transfer of object ownership in the parent child widget tree relies on it, and is why stack allocated QObjects are a bad idea. They can end up double-deleted if they are "linked" to a widget tree. I know that there is an argument that since main() is top level, anything created under main will be destroyed before main is...but!!!!

                                          I content that we should treat main(), and objects created in main, just as objects created in any other function with regard to the framework...the key here being consistency, rather than (in this case) necessity.

                                          As far as efficiency of heap vs stack, lets keep it in perspective. A few extra cycles to allocate a top level widget is negligible in the grand scheme.

                                          In my previous I took Schroeder to infer that main is (by necessity) suppose to be as small and trivial as possible, and I think I was trying to disarm that position as being more stylistic than code-quality oriented.

                                          S 離線
                                          S 離線
                                          SimonSchroeder
                                          寫於 最後由 編輯
                                          #20

                                          @Kent-Dorfman said in Where are the .ui files?:

                                          The transfer of object ownership in the parent child widget tree relies on it, and is why stack allocated QObjects are a bad idea.

                                          What I'm trying to say is that in C++ it is generally a good idea to put variables on the stack and not on the heap. And you are right that we need to be careful with Qt. Everything in Qt that has a parent assigned needs to be heap allocated (and not managed by a smart pointer!). However, the QApplication and the top-level widget don't have a parent assigned. This means that in a large application no widget will ever be destroyed because the parent (i.e. the MainWindow in my example) is never destroyed. That's why I advocate for the top-level widget to be on the stack. Otherwise, you should call app->exec(), store its return value, explicitely delete the top-level widget, and finally return the return value from app->exec(). Using a stack variable is much easier.

                                          I am so vocal about it because I was taught to use pointers and new everywhere when I started with C++. Turns out that this was the source of most bugs. So, using stack variables almost everywhere (except for Qt's objects with parents assigned) helps to prevent a lot of bugs. (There are other reasons to use pointers related to OOP and polymorphism, but even then there are fewer cases than I was taught initially.)

                                          Pl45m4P 1 條回覆 最後回覆
                                          3

                                          • 登入

                                          • Login or register to search.
                                          • 第一個貼文
                                            最後的貼文
                                          0
                                          • 版面
                                          • 最新
                                          • 標籤
                                          • 熱門
                                          • 使用者
                                          • 群組
                                          • 搜尋
                                          • Get Qt Extensions
                                          • Unsolved