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. Few basic questions about QT
QtWS25 Last Chance

Few basic questions about QT

Scheduled Pinned Locked Moved General and Desktop
19 Posts 4 Posters 4.3k 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.
  • N Offline
    N Offline
    noastick
    wrote on last edited by
    #1

    I am a begginer to QT programming and as I tried creating a GUI application I encountered some issues and questions:

    · I have a 'Client' class, that stores the data from clients. I made this class to be a Designer form class (as i want to create a window where the user can input the data). I made it so that the data is set when a button is clicked. My question is if a simple class that stores data should have a Designer form or if this two things should be done separately.

    · Regarding the last question, when i create the "client" widget (the window that will open when the user wants to enter client data) I have to do it as a pointer Client window = new Client window->show(). If not done this way, the widget opens and closes inmediately. But I have another class called "List" that is a template class. When I want to store the client object in a List, it doesn't work, as List doesn't accept pointers, but a concrete object (i hope you understand what i'm saying). What can I do to solve this? The best would be to be able to do this: Client window; window.show(); Without it closing.

    · Should I make the whole app on main.cpp or mainwindow.cpp? I mean, all the functions that make the app work and the different variables needed, should they exist on main.cpp or mainwindow.cpp? What is the right way to do it?

    Thanks

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

      You should separate your business logic (the data) from the GUI. i.e. you make a class or classes that know about the data required by the application. Then you have classes that are the GUI (the Widgets for forms and windows).

      1 Reply Last reply
      0
      • A Offline
        A Offline
        ambershark
        wrote on last edited by
        #3

        These are basically C++ questions and general programming and not-so-much Qt related. But here goes...

        1. I would separate the stored data and the form that allows input and editing of the data. So have an object Data and a GUI interface Form. Those names would be more appropriate to your project of course. :)

        2. Multiple ways to handle this one. The proper way is just to dereference the pointer (assuming your list takes a copy of it). So something like List::add(*myObject); The * does the magic on that one. Again if the List doesn't take a copy though and instead stores it by reference or pointer then when myObject is cleaned up it will cause crashing in the List when it is next accessed.

        The next way is you could use a QDialog instead of QWidget for your window then you can do a blocking call like so:

        @
        MyDialog dlg(this);
        dlg.exec();
        @

        When exec() returns it means the window has been closed. So you can then process your data without the use of the pointer.

        1. Lastly I use main.cpp for very very limited stuff. Everything else happens in files pertaining to their object. A pretty normal main.cpp for me is as simple as:

        @
        #include <QApplication>

        int main(int argc, char *argv[])
        {
        QApplication app(argc, argv);

        MyMainWindow mw;
        mw.show();

        return app.exec();
        }
        @

        Sometimes I add things like logger initialization and setting up the application object stuff like QCoreApplication::setOrginizationName("xx"); etc.

        My L-GPL'd C++ Logger github.com/ambershark-mike/sharklog

        1 Reply Last reply
        0
        • N Offline
          N Offline
          noastick
          wrote on last edited by
          #4

          Thank you for the answers!
          So now i've run into this:
          I have a structure that stores my "Clients". By touching a button I open a window where I create a new Client. Then I need to store that client in the structure mentioned before. The thing is , using a slot function, i have no way to pass that structure by reference, so it would be modified. Any suggestions?

          1 Reply Last reply
          0
          • A Offline
            A Offline
            ambershark
            wrote on last edited by
            #5

            I don't quite understand what you're saying here. Can you show me some code so I can get an idea of what you are trying to pass and how?

            My L-GPL'd C++ Logger github.com/ambershark-mike/sharklog

            1 Reply Last reply
            0
            • N Offline
              N Offline
              noastick
              wrote on last edited by
              #6

              [quote author="ambershark" date="1407809522"]I don't quite understand what you're saying here. Can you show me some code so I can get an idea of what you are trying to pass and how?[/quote]

              I would have a structure "Stack". Then i do:
              @
              connect(ui->pushButton,SIGNAL(clicked()),this,SLOT(AddToStack(Stack, Client)).
              @
              Do you understand? That code is for example only, it doesn't matter if it is correct.
              Thanks

              1 Reply Last reply
              0
              • A Offline
                A Offline
                ambershark
                wrote on last edited by
                #7

                Oh yea I see what you're saying now.

                For this I would use a class member. I would set the client struct when I created the widget to modify it. Then I could access that struct from the widget on the button clicked signal.

                Then finally I could get that client struct from outside the widget when it was done being processed.

                Example:

                @
                class MyWidget : public QWidget
                {
                public:
                void setClient(Client *client) { mClient = client; }
                Client *client() const { return mClient; }

                private slots:
                void buttonClicked();

                private:
                Client *mClient;
                };

                // implementation
                void MyWidget::buttonClicked()
                {
                mClient->setSomething(x);
                }
                @

                There are other ways to accomplish this as well. You could use a global (not recommended), you could use a custom pushbutton that emitted a signal with the client as a parameter (I wouldn't really do this either). You could use a static type accessor. Something like Client::clientList()->at(i); although I wouldn't do that either. They are all options but I would use the method I showed above.

                My L-GPL'd C++ Logger github.com/ambershark-mike/sharklog

                1 Reply Last reply
                0
                • N Offline
                  N Offline
                  noastick
                  wrote on last edited by
                  #8

                  [quote author="ambershark" date="1407879931"]Oh yea I see what you're saying now.

                  For this I would use a class member. I would set the client struct when I created the widget to modify it. Then I could access that struct from the widget on the button clicked signal.

                  Then finally I could get that client struct from outside the widget when it was done being processed.

                  Example:

                  @
                  class MyWidget : public QWidget
                  {
                  public:
                  void setClient(Client *client) { mClient = client; }
                  Client *client() const { return mClient; }

                  private slots:
                  void buttonClicked();

                  private:
                  Client *mClient;
                  };

                  // implementation
                  void MyWidget::buttonClicked()
                  {
                  mClient->setSomething(x);
                  }
                  @

                  There are other ways to accomplish this as well. You could use a global (not recommended), you could use a custom pushbutton that emitted a signal with the client as a parameter (I wouldn't really do this either). You could use a static type accessor. Something like Client::clientList()->at(i); although I wouldn't do that either. They are all options but I would use the method I showed above.[/quote]

                  Thank you for the very detailed anwer! I don't think my previous message was sent correctly. I understand how to manage the client class, the thing is how to store that "Client" class in a "Stack" class , which i need to be modified to be used in other parts of the program.
                  connect(ui->pushButton,SIGNAL),this,SLOT(client,stack).

                  That was the original message. A slot function that when i click a pushButton, it creates the client, then stores it in stack. AND stack is modified throughout the program.

                  Thanks!

                  1 Reply Last reply
                  0
                  • JeroentjehomeJ Offline
                    JeroentjehomeJ Offline
                    Jeroentjehome
                    wrote on last edited by
                    #9

                    Hi,
                    When you want to use a custom type in a signal/slot operation you will be able to use Q_DECLARE_METATYPE and then (not for QObject derived classes) those classes are available in Signal/Slot operations

                    Greetz, Jeroen

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

                      Ok just to make sure nomenclature isn't confusing this at all. When you say "stack" do you mean like the memory stack or are you talking about a custom class that you have called "stack" that contains a group of objects called "client"?

                      If you are talking about memory stack then there isn't a way to do what you're asking without copying those objects in places, or you could pass things along as a reference to the object. So Client& instead of just Client. I personally don't like that way though as it can get confusing and things can go out of scope, namely the first one which is what the others refer to.

                      If you are talking about the latter scenario let me know and I'll see if I can answer that for you as well.

                      My L-GPL'd C++ Logger github.com/ambershark-mike/sharklog

                      1 Reply Last reply
                      0
                      • N Offline
                        N Offline
                        noastick
                        wrote on last edited by
                        #11

                        [quote author="ambershark" date="1407914012"]Ok just to make sure nomenclature isn't confusing this at all. When you say "stack" do you mean like the memory stack or are you talking about a custom class that you have called "stack" that contains a group of objects called "client"?

                        If you are talking about memory stack then there isn't a way to do what you're asking without copying those objects in places, or you could pass things along as a reference to the object. So Client& instead of just Client. I personally don't like that way though as it can get confusing and things can go out of scope, namely the first one which is what the others refer to.

                        If you are talking about the latter scenario let me know and I'll see if I can answer that for you as well.[/quote]

                        I am sorry for using the wrong words. I meant a "stack" as a class that contains a group of "client" (another class) object.

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

                          Ok, in order to help you further I'm going to have to see some code. I need to see headers for Stack, Client, and parts that store the client in your window widget implementation.

                          My L-GPL'd C++ Logger github.com/ambershark-mike/sharklog

                          1 Reply Last reply
                          0
                          • N Offline
                            N Offline
                            noastick
                            wrote on last edited by
                            #13

                            [quote author="ambershark" date="1408660823"]Ok, in order to help you further I'm going to have to see some code. I need to see headers for Stack, Client, and parts that store the client in your window widget implementation.[/quote]

                            Well, I've realized that I don't know how to use variables with signal functions.
                            I created a* ClientW* class for inserting the client data. Then I have the Client class that stores the data. So when i finish on the ClientW window, I push 'Create' button and in the signal function:
                            @void ClienteW::on_pushButton_clicked()
                            {
                            QString name;
                            name=ui->lineEdit->text();

                            Cliente(name) client;
                            

                            }@

                            I create the client, but i see no way in which the main window gets the client data.

                            @void MainWindow::on_pushButton_clicked()
                            {
                            Cliente client;
                            ClienteW * w = new ClienteW;
                            w->show();

                            }@

                            EDIT:
                            I just thought of an easy example.
                            If I want the user to choose three options. The user presses a button, a menu opens (Widget) and the three options are available via Radio buttons. The thing is, after clicking "Done" in this widget, how would you do so that MainWindow receives the option selected?

                            Thanks!

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

                              Ok, there are a bunch of ways to do this.

                              1. You can use QDialog and exec() then when it returns pull the data you need. Here is an example:

                              @
                              void MainWindow::doSomething()
                              {
                              MyDialog dlg(this);
                              if (dlg.exec() == QDialog::Accepted)
                              {
                              // access the data you need here
                              bool myVar = dlg.radioButton->isChecked();
                              }
                              }
                              @

                              1. If sticking with a widget that you use new and show on. Oh and btw in your example since you do ClienteW *w = new ClienteW; without the parent that will memory leak as you have no way to clean that up later. If you do ClienteW *w = new ClienteW(this) that will have the parent clean it up. Although if you are going to call that a lot I would manage memory via delete w; yourself.

                              Anyway back to #2, if you use the widget like above, you can save off the pointer in a class member variable and then access that when you need it. I would have a signal or something that tells mainwindow the widget is done and it's ok to access it's data.

                              @
                              void MainWindow::doSomething()
                              {
                              mWidget = new ClienteW(this); // mWidget is a member of mainwindow
                              connect(mWidget, SIGNAL(widgetDone()), this, SLOT(clientWidgetFinished()));
                              mWidget->show();
                              }

                              void MainWindow::clientWidgetFinished()
                              {
                              if (mWidget)
                              {
                              // access it here
                              bool myVar = mWidget->radioButton->isChecked();

                                 // clean up
                                 mWidget->deleteLater();
                                 mWidget = 0;
                              

                              }
                              }
                              @

                              Not a fan of this method but it's an option.

                              1. You could also make ClientW aware of MainWindow or wherever you need the client data. Then inside ClientW when the radio is set you can call it to set the data in mainwindow, like so:

                              @
                              void ClientW::radioSelected()
                              {
                              // mMainWindow would be a pointer to mainwindow passed in the constructor
                              mMainWindow->clientSelection = radioButton->isChecked();
                              }
                              @

                              1. You could use a globally (static) available object to save the data in. Something you could access with a static function anywhere like Client::reference()->setRadioCheck(radioButton->isChecked()).

                              Personally I would use either #1 or #2. If you are still stuck I can give you a working example that you can compile and run to see how it works.

                              My L-GPL'd C++ Logger github.com/ambershark-mike/sharklog

                              1 Reply Last reply
                              0
                              • N Offline
                                N Offline
                                noastick
                                wrote on last edited by
                                #15

                                [quote author="ambershark" date="1409006265"]Ok, there are a bunch of ways to do this.
                                2. If sticking with a widget that you use new and show on. Oh and btw in your example since you do ClienteW *w = new ClienteW; without the parent that will memory leak as you have no way to clean that up later. If you do ClienteW *w = new ClienteW(this) that will have the parent clean it up. Although if you are going to call that a lot I would manage memory via delete w; yourself.

                                Anyway back to #2, if you use the widget like above, you can save off the pointer in a class member variable and then access that when you need it. I would have a signal or something that tells mainwindow the widget is done and it's ok to access it's data.

                                @
                                void MainWindow::doSomething()
                                {
                                mWidget = new ClienteW(this); // mWidget is a member of mainwindow
                                connect(mWidget, SIGNAL(widgetDone()), this, SLOT(clientWidgetFinished()));
                                mWidget->show();
                                }

                                void MainWindow::clientWidgetFinished()
                                {
                                if (mWidget)
                                {
                                // access it here
                                bool myVar = mWidget->radioButton->isChecked();

                                   // clean up
                                   mWidget->deleteLater();
                                   mWidget = 0;
                                

                                }
                                }
                                @

                                Not a fan of this method but it's an option.

                                [/quote]

                                Thanks for the detailed information! I like option #2. But I don't see how MainWindow would be able to use that bool variable, i mean, it seems as if the bool would stay inside the clientWidgetFinished function, right?. Am I missing something? (I don't want to use global variables).

                                Can the widgetDone function be a Clicked() function? The one that is the, for instance, pushButton signal.

                                Thank you. Sorry for answering so late, but i've been busy.

                                1 Reply Last reply
                                0
                                • A Offline
                                  A Offline
                                  ambershark
                                  wrote on last edited by
                                  #16

                                  If you needed access to that bool outside of the clientWidgetFinished() function you would make it a class variable. You will rarely need globals these days. In fact I would say I almost never use them and when I need global type variables they tend to be static members of a class.

                                  So if you added something like this:

                                  @
                                  class MainWindow : public QMainWindow
                                  {
                                  //...
                                  private:
                                  bool mMyMvar;
                                  };

                                  // and then in your function
                                  void MainWIndow::clientWidgetFinished()
                                  {
                                  //...
                                  mMyVar = mWidget->radioButton->isChecked();
                                  //...
                                  }
                                  @

                                  Now that mMyVar bool is accessible from anywhere in your class.

                                  My L-GPL'd C++ Logger github.com/ambershark-mike/sharklog

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

                                    Oh and forgot to answer your other question, yes widgetDone() was just a generic made up signal. It could absolutely be linked to the click of a pushbutton.

                                    @
                                    // assume pushbutton is called pushOK
                                    connect(pushOK, SIGNAL(clicked()), this, SLOT(clientWidgetFinished()));
                                    @

                                    My L-GPL'd C++ Logger github.com/ambershark-mike/sharklog

                                    1 Reply Last reply
                                    0
                                    • N Offline
                                      N Offline
                                      noastick
                                      wrote on last edited by
                                      #18

                                      [quote author="ambershark" date="1409957257"]Oh and forgot to answer your other question, yes widgetDone() was just a generic made up signal. It could absolutely be linked to the click of a pushbutton.

                                      @
                                      // assume pushbutton is called pushOK
                                      connect(pushOK, SIGNAL(clicked()), this, SLOT(clientWidgetFinished()));
                                      @
                                      [/quote]

                                      Thank you so much! I think I finally got it!
                                      If I need anything, I'll be posting here. Thanks again.

                                      1 Reply Last reply
                                      0
                                      • A Offline
                                        A Offline
                                        ambershark
                                        wrote on last edited by
                                        #19

                                        No problem, happy to help.

                                        My L-GPL'd C++ Logger github.com/ambershark-mike/sharklog

                                        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