Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. General talk
  3. Brainstorm
  4. [SOLVED] Generating a UI on the fly, Pt.2
QtWS25 Last Chance

[SOLVED] Generating a UI on the fly, Pt.2

Scheduled Pinned Locked Moved Brainstorm
18 Posts 2 Posters 7.2k 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.
  • V Offline
    V Offline
    valandil211
    wrote on last edited by
    #9

    [quote author="Andre" date="1309187153"] Why does a test inherit QWidget? I don’t know what kind of tests you’re talking about, but that does not seem to be most logical way to go. QObject I understand, but QWidget? That a test (-plugin) must be able to return a QWidget, does not mean that it should be a QWidget. [/quote]

    I'm not sure, really. In Qt Creator, I simply added a new Qt Designer form class, designed my test there, made the class inherit from an abstract class that contains some information about a particular category of test. This class inherits from QWidget, so that I can simply add a test to the MainWindow by writing

    @ cqpkvi2 = new CQpkVI2(this, 1);
    ui->gridLayout_2->addWidget(cqpkvi2);@

    The second argument simply toggles some functionality. Seemed like a good solution when I came up with it, but then again, I started programming a month ago.

    I think I'm beginning to understand why one would use plugins, but as far as I know (documentation on my tests is scattered in different places), my tests won't share a lot of code.

    Tell me if I'm wrong, but what you're proposing by using plugins, or approaching the problem as if I used plugins, is to break up my hypothetical huge switch statement into several smaller switch statements? I would know how to do that with the hierarchical class structure I'm using right now.

    Oh, BTW, what are you talking about when you say factory?

    Thanks!

    Joey Dumont

    1 Reply Last reply
    0
    • A Offline
      A Offline
      andre
      wrote on last edited by
      #10

      I think you have to realize, that the UI a test presents to set its parameters is something different from the test itself. It should be possible to instantiate the test itself without showing its UI, for instance if the parameters are already known. A test would therefore be represented by a class of some common base class, and either the test factory or the test class itself could supply a QWidget-based UI for the settings belonging to the class by means of a method that returns a QWidget*. That is: you need a has-a, not an is-a relationship.

      Why you would want to have a modular design, is that you are bound to want to change the set of tests at one time or another. That will lead to problems if you did not properly modularize from the start. I don't know what class structure you now use; you did not tell us about any of that. So it is hard to comment on that. It is hard to imagine you using a big class hierarchy in a useful way, while still claiming that your tests don't share a lot of code...

      A "factory":http://en.wikipedia.org/wiki/Factory_method_pattern is a term from a design pattern. Basically, it is an object with a known interface that can create instances of other objects. That sounds vague, I know, but it is really useful. In the case of plugins, you can have your plugin only export a factory, and let that factory tell the host application about the concrete tests supported, and supply a method to instantiate those test objects.

      1 Reply Last reply
      0
      • V Offline
        V Offline
        valandil211
        wrote on last edited by
        #11

        [quote author="Andre" date="1309189454"]It should be possible to instantiate the test itself without showing its UI, for instance if the parameters are already known. [/quote]

        Could I do that by keeping the same code as I have now (since I use Qt Creator and Designer, I have a ui_{fileTitleHere}.h, class.h, class.cpp and class.ui files)? Can I just move the setupUi(this) command to a function that is called only when a certain condition is met?

        Is there another way of doing that?

        [quote author="Andre" date="1309189454"] I don’t know what class structure you now use; you did not tell us about any of that. So it is hard to comment on that. It is hard to imagine you using a big class hierarchy in a useful way, while still claiming that your tests don’t share a lot of code…[/quote]

        The class structure's main purpose is to provide a certain organization to the tests. (The tests are already divided in several categories, the class hierarchy only makes this apparent in the source code.) A few of the tests are similar indeed.

        As for the factory concept, I printed out some pages of Design Patterns: Elements of Reusable Object-Oriented Software, do you think it's a good place to start?

        Thanks again for all your tips,

        Joey Dumont

        1 Reply Last reply
        0
        • A Offline
          A Offline
          andre
          wrote on last edited by
          #12

          I would not use the structure you have now. I would separate the UI parts and the functional parts of your tests into separate classes (which can, if you want, be defined in a single file). That also makes it possible to share a GUI between more than one test, for instance by using some parameters. Is it possible? Yes. Is it wise? No, I don't think so.

          Don't use class hierarchies just as a tool for organization. That doesn't make much sense. Only do that if there is really a technical reason for such a design. The Design patterns book is a good start, but it is a bit abstract I find.

          1 Reply Last reply
          0
          • V Offline
            V Offline
            valandil211
            wrote on last edited by
            #13

            Let me recapitulate (I will also try to incorporate practical steps in my summary, so you can tell if I'm wrong).

            I create classes for each of my test which contain:

            Members that hold the results of a test;

            Functions that fetch and insert data in DB

            Possibly other functions

            Depending on the test's results, I create GUIs that can be shared amongst multiple tests.

            I then create a factory that determines which GUI goes with what test.

            Factory contains functions that decides which test+GUI to instantiate depending on query from DB.

            Something like that? If so, that raises some questions.

            [Edit: How do you nest lists?]

            Joey Dumont

            1 Reply Last reply
            0
            • A Offline
              A Offline
              andre
              wrote on last edited by
              #14

              Eh... no.

              Perhaps the issue here is that I don't fully understand what your tests are all about, and where the GUI for them comes into the picture. I had assumed the GUI is for setting parameters for a test, and a test itself can be run without a GUI as long as the parameters are known. If those assumptions are false, please be more specific on your needs. You can not assume that we understand your needs, if you don't explicitly tell us about them.

              Yes

              Yes, I guess. I don't know what your tests return.

              I guess so, if that is where your configuration data is stored.

              Sure.

              This one, I don't get. I'd say that every test that would need configuration, should be able to create a GUI to allow configuration. That would imply that it has nothing to do with results. A GUI class might be shared between tests, if two tests need the same type of configuration that you can adjust with some simple parameters (a single number, for instance).

              No, you need the factories to actually create the test instances. A factory supplies:

              Information on what tests are supported

              A way to create object instances for those test

              Optionally, other information on those tests, such as human-readable names or other meta-data

              Depending on your design, a way to create a GUI for a test (could also be a method of the test class itself)

              Who decides which tests to run, is completely separate from the above.

              1 Reply Last reply
              0
              • V Offline
                V Offline
                valandil211
                wrote on last edited by
                #15

                Sorry Andre. Here's the "background info":http://developer.qt.nokia.com/forums/viewthread/7221/ you need.

                For instance, the screenshot I posted shows a form for a test that is performed on a machine. The four white LineEdits expect a numerical value, which will get inserted in the DB when user clicks Submit (not yet implemented). The four grayed-out LineEdits contain values that are stored in the DB and correspond to expected and tolerances values for this test.

                Moreover, I want to be able to display data from the DB in the four white LineEdits if necessary, but that I already know how to do.

                I hope the situation is clearer and, please, let me know if you need anything else.

                Joey Dumont

                1 Reply Last reply
                0
                • V Offline
                  V Offline
                  valandil211
                  wrote on last edited by
                  #16

                  Hello again!

                  I've read about several patterns in Design Patterns: Elements of Reusable Object-Oriented Software in the past few days. However, I don't see how it helps me. Again, here's a "recap":http://developer.qt.nokia.com/forums/viewthread/7221/ of what I want to do.

                  Both the Abstact Factory and Factory Method require subclassing an abstract Creator class that instantiates its subclasses using conditional statements. !https://lh4.googleusercontent.com/-sHPvGeYFGgs/ThH0noZ0JCI/AAAAAAAAB4Y/qjmP-wzMI_k/s800/ClassDiagram.jpg(Sample diagram for "Factory Method")!

                  Imagine this with 300+ tests. In a given set, I might have about 50 tests. To instantiate a test, I'm dependant upon a table similar to this one:
                  [quote author="Joey Dumont" date="1309147389"]
                  @
                  PK FK to Group FK to Test
                  1 1 1
                  2 1 2
                  3 1 3
                  @
                  [/quote]

                  Hence the CreateTest(int) could have a switch statement that instantiates a subclass depending on the value in the table above. Now, we already said this was ridiculous, because a switch with 300+ cases seemed like a weak solution.

                  Now, the other solution could be this (imagine it with 15-20 classes after each category class).
                  !https://lh6.googleusercontent.com/-NRA-CcM9Gro/ThH57btXtVI/AAAAAAAAB4g/fH9q3p2dQwQ/s800/ClassDiagram2.png(Bigger class hierarchy. )!

                  Because I have access to the integers characterize the group and category of each test, I could divide my switch statement with this. Filters are applied to isolate a group, then a category, then the instantiation takes place. At this level, there are about 15 to 30 tests per category, making a switch statement viable (I think).

                  Any thoughts? Lemme know if you want to explain my ideas in more detail. It would be my pleasure.

                  Joey Dumont

                  1 Reply Last reply
                  0
                  • A Offline
                    A Offline
                    andre
                    wrote on last edited by
                    #17

                    I would not bind my db structure to my application structure that tightly. You may come to regret that. I think I have told you before how I would go about this. I really don't know how much more I can tell you short of writing the code for you. To reiterate, what I would do, given what I understand of your application:

                    I would create my tests in plugins, where each plugin may contain 1..N tests. Each plugin has as its entry-point a factory object that tells the application loading the plugin what tests are supported, and optionally delivers other meta-information on the supported tests. The factory can create instances of the tests it supports, and return them. Then, either you give each test a function like this:
                    @
                    QWidget* createTestConfigurationGui();
                    @

                    or you give each factory a method like this:

                    @
                    QWidget* createTestConfigurationGui(const QString& testName);

                    //this is needed anyway:
                    AbstractTest* createTestInstance(const QString& testName);
                    @

                    The implemenation of createTestInstance would of course contain a switch-like construction to instantiate an instance of the correct test, but because you keep the test in logical groups in different plugins, those constructions say of a reasonable size (not 300...)

                    1 Reply Last reply
                    0
                    • V Offline
                      V Offline
                      valandil211
                      wrote on last edited by
                      #18

                      Thanks Andre. I think I know how I'll go about and design this.

                      Joey Dumont

                      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