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. Running into problems using a simple gui multithreaded application. FRUSTRATED AND NEED HELP !
Forum Updated to NodeBB v4.3 + New Features

Running into problems using a simple gui multithreaded application. FRUSTRATED AND NEED HELP !

Scheduled Pinned Locked Moved General and Desktop
22 Posts 4 Posters 7.3k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    alonhalawi
    wrote on last edited by
    #11

    The reason of me loosing my nerve is that it supposed to be very simple.

    If I had the ability to draw a rectangle on the screen and paint it according to anything, I have many ways to do it.

    The only reason I chose Qt is for the graphics.

    And it takes me a lot of digging, and getting to know the UI, the objects and the threading mechanisms, I mean, forcing me to read all of this stuff, then experiment, then I see what I have to define to make this simple stuff to work.

    I'm positive I have missed something, but I am not going to port all my python work in PySide.

    Look at the requirement for making this work:

    1. manage signals and slots
      1.1 define slots for functions you want to invoke
      1.2 define signals (so you could emit the slots)
      1.3 connect the signal(s) to the slot(s)
      1.4 make sure it's a queued connection (it wouldn't work otherwise)
    2. use a thread, not a process [1]
      2.1 use the moveToThread when creating
      2.2 use signal to emit changes on the gui (&make sure the func ends)
      2.3 use QtGui.QApplication.processEvents() to force the updates when the func doesn't end

    I can go on ..

    All this stuff to handle, none of this belongs to the code itself, only preparations ..

    [1] BTW in c, syncing threads is with mutexes, and using globals, syncing process is different but they communicate with ipc e.g. mq, sockets, shm ..

    How is any of this comfortable ?

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

      I bet something is wrong with this code:

      main.py
      @
      AA_Instance=AA_Tester.MainAA(shared_objects)

      app = QtGui.QApplication(sys.argv)
      form = MainDialog(shared_objects=shared_objects, AA_Instance=AA_Instance)
      form.show()
      app.exec_()
      @

      maindialog.py
      @
      class MainDialog(QtGui.QDialog, pages5.Ui_Pages):

      def init(self, parent = None, shared_objects, AA_Instance):

      self.AA = AA_Instance

      self.thread = QtCore.QThread()
      self.AA.moveToThread(self.thread)
      self.AA.run_test.connect(self.AA.test)
      self.thread.start()
      @

      the thread doesn't start

      1 Reply Last reply
      0
      • Chris KawaC Offline
        Chris KawaC Offline
        Chris Kawa
        Lifetime Qt Champion
        wrote on last edited by
        #13

        [quote author="alonhalawi" date="1405262476"]
        Look at the requirement for making this work: (...)[/quote]

        1. Yes, you need to learn library to properly use library. What's the problem?
          1.1 one line
          1.2 one line
          1.3 one line
          1.4 no code (if you know the library)
        2. If you're a programmer you should know the difference anyway. You can actually make it work with both. It's just different.
          2.1 QObject belongs to a thread it was created in. If you create the worker inside the running thread no need to use moveToThread, one line otherwise
          2.2 one line. What do you mean make sure it ends? It ends. It's a function call. If you mess up the setup and it directly calls lengthy slot then of course it doesn't end. What is surprising about that?
          2.3.No, you should not use processEvents. It's for cases when your code is so messed up you can't find other ways to fix it. It's a lifeboat, not a yaht. Should not happen in such a simple case. And again - a UI update should be a small function that ends right away. Don't do lengthy stuff in UI slots.

        [quote]I can go on ..[/quote]Please do. (Denholm Reynholm ref. :) )

        So, I counted 3-4 lines of preparation code (not counting the actual user code that does stuff) and one line (the emit) to make an asynchronous data exchange between threads. Sounds simple to me, but I can agree to disagree.

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

          I must have forgot the target, but as according to the examples I have, the placing of the function that I want to call as a thread is not done like this

          QtCore.QThread(target= ***)
          *

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

            Hey, why don't you point your questions to the Python group? Maybe some of those Python experts over there can help you.

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

              I'm considering moving the graphics to python. It's just exhausting missing some property, or widget attribute, or another feature that forces you to read a whole document of an object in qt ..

              I do not go lengthly on the slot. I make a simple short change and go out, when it doesn't work I try looking for more examples that look similar to what I need.

              I think I'll just do it with python, one line + one line + one line + noline with feature parameter queue-connection + reading another library kinda making me change my mind.

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

                Got it figured out, and done ...
                with python.

                Sorry Qt fans, I admit, I am a noob to Qt, I find it very non-scalable, however I truly recommend python (for graphics as well), and did it with less than a day (I studied most of the gui stuff)

                simple, scalable, comfortable ... and most importantly, can adapt to more then one design option of mine.

                1 Reply Last reply
                0
                • Chris KawaC Offline
                  Chris KawaC Offline
                  Chris Kawa
                  Lifetime Qt Champion
                  wrote on last edited by
                  #18

                  If it's right for you then... well, it's right for you :)

                  Just as a comment - You made it in less then a day. Yup, for that size of apps Python might be the easier and faster option. But claiming Qt is not scalable... you clearly didn't do your research :)

                  1 Reply Last reply
                  0
                  • Chris KawaC Offline
                    Chris KawaC Offline
                    Chris Kawa
                    Lifetime Qt Champion
                    wrote on last edited by
                    #19

                    Out of curiosity (and some boredom) I implemented a thread changing a color of a button every second. It took me < 5 minutes and there are exactly the 5 lines I was talking about needed to make threading work.
                    If you're not busy I would really like to see what it looks like in Python(without Qt). I don't mean to bash, I'm really curious.

                    @
                    class Worker : public QObject {
                    Q_OBJECT
                    public:
                    void doWork() {
                    while(true) {
                    QThread::currentThread()->sleep(1);
                    // 5 - emit the signal
                    emit foo(rand());
                    }
                    }
                    signals:
                    void foo(int);
                    };

                    class UI : public QPushButton {
                    public:
                    UI(QString text, QWidget* parent = nullptr) : QPushButton(text, parent) {
                    // 1 - start the thread
                    connect(this, &UI::clicked, &{ workerThread.start(); });
                    // 2 - fire up doWork in the thread
                    connect(&workerThread, &QThread::started, &worker, &Worker::doWork);
                    // 3 - modify ui in response to signal
                    connect(&worker, &Worker::foo, this, &UI::changeColor);
                    // 4 set thread affinity of worker object
                    worker.moveToThread(&workerThread);
                    }
                    private:
                    void changeColor(int color) {
                    setStyleSheet(QString("background-color: ") +
                    QColor::fromRgba(color).name());
                    }
                    Worker worker;
                    QThread workerThread;
                    };

                    int main(int argc, char *argv[])
                    {
                    QApplication a(argc, argv);
                    UI ui("hello");
                    ui.show();
                    return a.exec();
                    }@

                    1 Reply Last reply
                    0
                    • A Offline
                      A Offline
                      alonhalawi
                      wrote on last edited by
                      #20

                      sure, I'll post it, and also, out of curiosity, I'll go over the code you've posted to see what I've missed.

                      Right now, I have to get the whole project done, and also I am going to a trip in Europe tonight, so I will post the code when I get back.

                      It will probably be next Saturday.

                      I didn't mean to be such an **hole in this post, but I really don't do gui, so ..

                      I guess I need to invest my time to learn Qt the way it should, before I judge the lang.

                      1 Reply Last reply
                      0
                      • A Offline
                        A Offline
                        alonhalawi
                        wrote on last edited by
                        #21

                        Will upload it very soon. Just got back from Prague :)

                        1 Reply Last reply
                        0
                        • A Offline
                          A Offline
                          alonhalawi
                          wrote on last edited by
                          #22

                          Sorry for the delay, as I promised I am uploading the code.

                          Gui.py
                          @
                          import Tkinter as Tk
                          from PIL import Image, ImageTk
                          import tkMessageBox as tkMsgBox

                          def version_click(shr_objs):
                          print "version_click is called"
                          print 'this is my global segment:', shr_objs
                          tkMsgBox.showinfo('say hello', 'hello world')

                          def setupUi(MainDlg, shr_objs = None):
                          #setting up all the images and other stuff
                          raw_img_good = Image.open('images/good.jpg')
                          MainDlg.img_good = ImageTk.PhotoImage(raw_img_good)

                          #setting up all the widgets, and if needed, putting pictures to them
                          MainDlg.bg = Tk.Label(MainDlg)
                          MainDlg.bg.pack(expand=Tk.YES, fill=Tk.BOTH)
                          MainDlg.bg['image'] = MainDlg.img_bg

                          MainDlg.btnVer = Tk.Button(MainDlg, text='start', command = (lambda: start_click(shr_objs) ) )

                          widgets can be arranged using three main geometry managers: pack, grid and place, for this example I chosed pack (the recommended and simplest)

                          MainDlg.btnVer.pack()

                          MainDlg.btnVer.place(x=620, y=650, width=100, height=40)

                          if name == 'main':
                          MainDlg = Tk.Tk()
                          setupUi(MainDlg, {'action': 'init'})

                          MainDlg.mainloop() # for a gui app only enable this, or just run with -i option (interactive mode)

                          @

                          main.py
                          @
                          #!/usr/bin/python

                          import threading
                          import sys, time
                          import Gui
                          import Tkinter as Tk

                          import AA_Tester

                          shared queue object

                          mqGui2AA = mp.Queue()

                          global vars dictionary, I can choose any IPC I want here ..

                          shared_objects = {'action': 'init', 'mqGui2AA':mqGui2AA}
                          #shared_objects = {'action': 'init'}

                          creating main gui form

                          MainDlg = Tk.Tk()
                          Gui.setupUi(MainDlg, shr_objs = shared_objects)

                          shared_objects['MainDlg'] = MainDlg

                          AA = AA_Tester.MainAA(shared_objects)

                          MainDlg.mainloop()
                          @

                          partial file from AA_Tester.py
                          @
                          MainDlg = shr_objs['MainDlg']
                          MainDlg.bg['image'] = MainDlg.img_good
                          @

                          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