[SOLVED] Qt philosophy? ("+" for "JKSH", "lpapad" and "sierdzio")



  • Are there any more philosophically oriented tutorials to Qt programming?
    Something that explains the thought models of the message/slot usage,
    signals, threads, etc. and how they should affect the architecture of the program.

    I think I know my way around plain C++ and I'm somewhat familiar with internals of some operating systems, so
    I'm not after beginner's C++ tutorial or 100-page explanation of what concurrency is.



  • These 4 sessions of presentation might be usefull.

    http://www.youtube.com/watch?v=L1VFNqr5NFk



  • Unfortunately, not much. It seems to be the same kind of "how to code this detail" tutorial as the other tutorials are. Very little about the thoughts behind the mechanisms or the mechanisms themselves. Half of it being C++.
    Some points, though, like that the QApplication::exec() is basically eventloop.

    (Also the presenter is irritatingly slow.)



  • A more technical article regardins signal/slot

    http://woboq.com/blog/how-qt-signals-slots-work.html


  • Moderators

    Please search the official documentation, it contains not only class documentation, but also some general descriptions of the technology:



  • [quote author="lpapad" date="1380829729"]A more technical article regardins signal/slot

    http://woboq.com/blog/how-qt-signals-slots-work.html[/quote]

    Very interesting and enlightening article. Thanks.



  • [quote author="sierdzio" date="1380871924"]Please search the official documentation, it contains not only class documentation, but also some general descriptions of the technology:

    The documentation just doesn't give the idea.
    Like:

    • why do the threads have affinities? Can something in a new thread update data in GUI, and if not, then why not?

    • Are threads concurrent or just asynchronous? If I start two threads that are supposed to communicate each other, can I be sure one is not executed after the other - like re-using a threadpool thread?

    • How about threads with shared (global) data?

    -Is it the convention that each class should be implemented in its own file?

    • if there are several ways GUI can interact with model, which ways are preferred in which situations?

    • How do the .ui files fit into the picture?

    • Is it the convention that the main function should only set up the application-wide things, or what should be in it?

    • Is the meta object system the key to this all?

    • How should HW interfaces be handled? Is there a conventional way to access the host OS system calls or...?


  • Moderators

    Hi,

    [quote]- why do the threads have affinities?[/quote]

    [quote]Can something in a new thread update data in GUI, and if not, then why not?[/quote]

    [quote]- Are threads concurrent or just asynchronous?[/quote]By definition, threads run in parallel if you have multiple cores. If you only have a single core (or if you have more threads than cores), the system will use time-slicing to give the illusion of parallelism. This applies to all threads, not just Qt threads.

    [quote] If I start two threads that are supposed to communicate each other, can I be sure one is not executed after the other - like re-using a threadpool thread?[/quote]Again, threads are concurrent. I'm not 100% sure what you're asking here, but this might have answers for you:

    ...see also the link in the next section:
    [quote]- How about threads with shared (global) data?[/quote]

    [quote]-Is it the convention that each class should be implemented in its own file?[/quote]This is something each development team sits down to discuss together. Qt's convention is to have one public class per file, but there could be other private classes in the same file. There is no benefit or penalty to you whether you follow or ignore this convention.

    [quote]- if there are several ways GUI can interact with model, which ways are preferred in which situations?[/quote]Please be more specific. Do you have examples of different ways of interaction?

    [quote]- How do the .ui files fit into the picture?[/quote]

    [quote]- Is it the convention that the main function should only set up the application-wide things, or what should be in it?[/quote]Again, your development team should discuss this together. But in C/C++ (not specific to Qt), yes, a common convention is to have main() set up application-wide things. This can be tidied up by having main() call static functions in main.cpp.

    [quote]- Is the meta object system the key to this all?[/quote]Key to what all? What's missing from sierdzio's second link?

    [quote]- How should HW interfaces be handled? Is there a conventional way to access the host OS system calls or...?[/quote]Qt is a cross-platform framework, so just use Qt's built-in classes. They abstract away the underlying HW implementation.


  • Moderators

    Thanks JKSH for going through this so deeply. I was busy attending the DevDays in the meantime :)

    turboscrew if there is anything more unclear, please ask. In general, a lot of your questions are general OS/ C++ knowledge, which is indeed out of scope of Qt documentation. Most of your threading questions are covered by the docs, as JKSH mentioned.



  • Thanks. I'll go through the links.

    "By definition, threads run in parallel if you have multiple cores. If you only have a single core (or if you have more threads than cores), the system will use time-slicing to give the illusion of parallelism. This applies to all threads, not just Qt threads."

    Not the case with .NET.

    "In general, a lot of your questions are general OS/ C++ knowledge"
    I don't think so. I was asking if there are "common conventions".

    You can write all C-code in one file and one function very much in a Basic-like way - the language doesn't stop you - but don't expect your code to be accepted anywhere.

    About GUI interaction with a model, I mean like in Java, you are supposed to use notification events, and with C#/WPF you use bindings.
    You CAN do it other ways, but those are generally encouraged.

    I'd think that the threading and signal/slot system have an intended role, and they are supposed to affect the program structure, but how?

    Also. I don't think that when a framework hides the OS and handles things outside the standard language, the questions about how the things should be done with that framework really are about anything "general".

    I'm very new to Qt, but not to programming or C++ or OSs.
    (More than 20 years of experience about embedded SW.)



  • This reveals something:

    bq. Creating and destroying threads frequently can be expensive. To reduce this overhead, existing threads can be reused for new tasks. QThreadPool is a collection of reuseable QThreads.

    bq. To run code in one of a QThreadPool's threads, reimplement QRunnable::run() and instantiate the subclassed QRunnable. Use QThreadPool::start() to put the QRunnable in the QThreadPool's run queue. When a thread becomes available, the code within QRunnable::run() will execute in that thread.

    bq. Each Qt application has a global thread pool, which is accessible through QThreadPool::globalInstance(). This global thread pool automatically maintains an optimal number of threads based on the number of cores in the CPU. However, a separate QThreadPool can be created and managed explicitly.

    => Thread are asynchronous, but not necessarily parallel (thread re-use).
    A separate new threadpool can be used, though.
    Looks a lot like .NET threading.

    Where did it come that in O-O circles the"only right way" to do threading is to make the threads program-internal processes (all with their own resources). "The object lives in a thread..." = objects are resources of threads.

    bq. Qt is a cross-platform framework, so just use Qt’s built-in classes. They abstract away the underlying HW implementation.

    And if there is no such class... (a more exotic device)


  • Moderators

    [quote]"By definition, threads run in parallel if you have multiple cores. If you only have a single core (or if you have more threads than cores), the system will use time-slicing to give the illusion of parallelism. This applies to all threads, not just Qt threads."

    Not the case with .NET.[/quote]It's also the case with .NET. From "Threads and Threading, .NET Framework 4.5":http://msdn.microsoft.com/en-us/library/6kac2kdh.aspx:

    "Because each time slice is small, multiple threads appear to be executing at the same time, even if there is only one processor. This is actually the case on multiprocessor systems, where the executable threads are distributed among the available processors."

    [quote]=> Thread are asynchronous, but not necessarily parallel (thread re-use).
    A separate new threadpool can be used, though.
    Looks a lot like .NET threading.[/quote]I don't quite follow your argument. Can you please explain how reusability and parallelism are mutually exclusive?

    Remember:

    • The degree of parallelism you can achieve is limited by the number of physical cores you have
    • In a typical non-microcontroller OS today, no program gets truly exclusive access to any core, because the processes that the OS spawns at startup already outnumber the cores in a typical machine.

    [quote]Where did it come that in O-O circles the"only right way" to do threading is to make the threads program-internal processes (all with their own resources). "The object lives in a thread..." = objects are resources of threads.[/quote]A more accurate comparison would be: "The object lives in this thread" = "The object runs its slots in this thread".

    Aside from a thread's dedicated stack, the OS has no concept of "this resource belongs to this thread". Any such philosophical association is created only to help developers visualize and manage the system.

    [quote][quote]Qt is a cross-platform framework, so just use Qt’s built-in classes. They abstract away the underlying HW implementation.[/quote]And if there is no such class... (a more exotic device)[/quote]Ah, you meant external hardware. Sorry, I thought you meant hardware on your PC.

    Anyway, it depends on your communications protocol. If you can, just use QTcpSocket, QUdpSocket or QSerialPort to send/receive commands. If you can't, write your own driver as you would with any other embedded system.

    You can use the QIODevice interface with your driver to get automatic signal emission when data is read/written, or you can use a plain old C++ class that sets flags to communicate with your engine. I would generally go for the first option.

    [quote]I was asking if there are "common conventions".

    You can write all C-code in one file and one function very much in a Basic-like way - the language doesn't stop you - but don't expect your code to be accepted anywhere.[/quote]The documentation has many compilable examples, some of which span many files. Study them to get an feel of the conventions in use.


  • Moderators

    [quote]I'd think that the threading and signal/slot system have an intended role, and they are supposed to affect the program structure, but how?

    ...

    I'm very new to Qt, but not to programming or C++ or OSs.
    (More than 20 years of experience about embedded SW.)[/quote]I think I better understand your questions and where you're coming from now.

    Qt is an event-driven framework. Qt encourages developers to write asynchronous code that react to to signals. Signals are simply function declarations; slots are simply functions that run whenever a connected signal is emitted. The meta-object compiler adds a definition to the signal at compile-time, to hook it into the event system.

    The signal-slot mechanism is an extension of traditional event systems. The differences are:

    • Simpler interfaces, more flexible, more extensible:
      ** In Java, the sender needs to create special Event objects and the receiver needs to implement the relevant Listener interface.
      ** In Qt, a signal can be connected to any function with a parameter list that matches the parameter list of the signals. It is trivial to create a new high-level signal: Just create a new function prototype with a descriptive name. No need to create a whole new class.
    • Easy to use in a multithreaded environment:
      ** Java needs all events to be dispatched from one thread.
      ** In Qt, all threads can emit signals which can be received by any other thread. In fact, this is the preferred way of inter-thread communications, as mentioned in one of the links I sent you.

    Having said that, Qt reduces the need for developers to create threads.

    • Traditionally, you'd implement timers and networking by getting a thread to poll and sleep periodically.
    • Qt exposes an asynchronous API to accomplish this, so you can (and often should) implement everything in the main thread.
      ** To be precise, Qt's networking classes use threads behind the scenes, but this is abstracted away from developers

    For the purposes of discussing GUI implementations below, forget about threads and think of asynchronous execution only.

    [quote]About GUI interaction with a model, I mean like in Java, you are supposed to use notification events, and with C#/WPF you use bindings.
    You CAN do it other ways, but those are generally encouraged.[/quote]Generally, the GUI emits signals to announce that the user has done something (clicked a button, selected a menu item). These signals are connected to the engine's slots, which run when the GUI emits a signal. The same thing happens the other way -- the engine emits signals to announce that processing has finished, announce that a network packet has arrived, provide the GUI with updated data, etc. The GUI slots respond to those signals and update themselves.

    C++ GUIs use signals+slots only.

    QML GUIs use a combination of signals+slots and bindings.

    Signals+slots aren't restricted to GUI interaction; you can also do event-driven data processing.



  • "Ah, you meant external hardware. Sorry, I thought you meant hardware on your PC."
    Oh, on my PC I could have a data board os DSP board or...

    But now you are speaking a language I understand. ;-)

    When it comes to .NET, I once made a trial - 3 threads generating output strings: thread identification + number with 1 second between outputs.
    First the first thread run to the end, then the second started and run to the end, and then the 3rd. Not really parallel even with dual core processor.

    Now if the threads should have exchanged the data...

    Also threads shouldn't depend on HW.


  • Moderators

    [quote author="turboscrew" date="1381388366"]"Ah, you meant external hardware. Sorry, I thought you meant hardware on your PC."
    Oh, on my PC I could have a data board os DSP board or...

    But now you are speaking a language I understand. ;-)[/quote]Too many languages out there; I don't always pick the best one off the bat ;)

    You'll probably find that desktop programmers think very differently from embedded system programmers. I'm guessing that's why you started this discussion.

    [quote]When it comes to .NET, I once made a trial - 3 threads generating output strings: thread identification + number with 1 second between outputs.
    First the first thread run to the end, then the second started and run to the end, and then the 3rd. Not really parallel even with dual core processor.[/quote]Hmm... Can't comment much without seeing your implementation or knowing what else your system was running at the time.

    In any case, the OS is the one that decides when each thread runs, and for how long before the thread has to yield.

    [quote]Now if the threads should have exchanged the data...[/quote]Then you must "synchronize them":http://doc-snapshot.qt-project.org/qt5-stable/threads-synchronizing.html. The page even links to examples that show you how to do that. MSDN would probably have similar examples.

    [quote]Also threads shouldn't depend on HW.[/quote]How do you propose making a single-core CPU and a dual-core CPU handle 2 threads the same way?

    May I ask what kinds of OS'es you've been working with?



  • "In any case, the OS is the one that decides when each thread runs,"
    No, it's the thread scheduling policy within framework or language runtime.
    (threadpool handling).

    "Then you must synchronize them"
    Queues are used for asynchronous communications - no synchronization needed. Also synchronization is not always needed with global "atomic" data that has one writer and many readers, although synchronization is recommended even then.

    "How do you propose making a single-core CPU and a dual-core CPU handle 2 threads the same way?"
    If threading is time-slicing that utilizes n cores.
    Very common way. Threads usually work even concurrently with single core.

    "May I ask what kinds of OS’es you’ve been working with?"
    Windows (NT, CE, 2000)
    Linux
    ChorusOS
    OS9
    OSE for DSP
    OSEck
    And a couple of proprietary OSes.
    No OS (bare iron)

    Those are the OSes that I have written kernel level code for.
    There are then some OSes that I have used, but not written kernel level code for.

    Also, not OSes, but environments: Ada and Occam.

    I'm also quite familiar also with pthreads.


  • Moderators

    [quote author="turboscrew" date="1381467762"]"How do you propose making a single-core CPU and a dual-core CPU handle 2 threads the same way?"
    If threading is time-slicing that utilizes n cores.
    Very common way. Threads usually work even concurrently with single core.[/quote]You know, that is how I, and the .NET documentation, have been describing thread management all along.

    [quote author="turboscrew" date="1381467762"]"In any case, the OS is the one that decides when each thread runs,"
    No, it's the thread scheduling policy within framework or language runtime.
    (threadpool handling).[/quote]A framework defers to the OS for thread scheduling. Linux, for example, only supports the PTHREAD_SCOPE_SYSTEM contention scope, not PTHREAD_SCOPE_PROCESS. Thus, the OS allocates time slices to all threads from all processes as one big group.

    All threadpool threads in Qt and .NET run in parallel. However, Qt and .NET do NOT use thread pools exclusively for multithreading.

    In your .NET test, you did not say:

    • Whether you used the thread pool or standalone threads.
    • How you configured your threads.
    • Where your CLR was hosted -- Some hosts can limit your threadpool size.

    If you had used a threadpool size of 1 to run your test, that would explain your results.

    [quote author="turboscrew" date="1381467762"]"May I ask what kinds of OS’es you’ve been working with?"
    Windows (NT, CE, 2000)
    Linux
    ChorusOS
    OS9
    OSE for DSP
    OSEck
    And a couple of proprietary OSes.
    No OS (bare iron)

    ...

    I'm also quite familiar also with pthreads.[/quote]The Linux implementation of Qt threads uses pthreads. If you're interested in the implementation details: https://qt.gitorious.org/qt/qtbase/source/src/corelib/thread/qthread_unix.cpp

    On Windows, Qt uses Win32 threads. The other OS'es you listed aren't supported.

    [quote author="turboscrew" date="1381467762"]"Then you must synchronize them"
    Queues are used for asynchronous communications - no synchronization needed. Also synchronization is not always needed with global "atomic" data that has one writer and many readers, although synchronization is recommended even then.[/quote]If you had opened the link I gave you, you would have found a detailed explanation on how to use signals and slots pass messages between threads through event queues, and why that approach is recommended approach over thread locking (traditional synchronization).

    Speaking of which, you started this discussion looking for insight into the underlying mechanisms that drive Qt applications. Multithreading aside, have you found answers to your questions yet?



  • Threadpool threads run in parallel, but .NET threading by default lets the framework to decide how many threads to use and which threads to reuse.
    I don't think (my example) that time slice could have been 10 seconds.

    You can use standalone threads with C#/WPF too, but not directly. At least you need to define the job "long lasting".

    I have tried to use the signals/slots, and I think that's the way it should work in O-O environment. Nice!

    bq. Speaking of which, you started this discussion looking for insight into the underlying mechanisms that drive Qt applications. Multithreading aside, have you found answers to your questions yet?

    Some of it. The picture is forming...

    I'll check the Linux implementation as soon as I have little time. Thanks for the link!



  • More concrete questions:

    I'm writing a simple external device commander that "discusses" with the computer via serial port. There are two kinds of commands: simple one line commands and a bit more complex multiblock commands. A block is some hundreds of bytes long. Simple command is just a couple of tens of bytes long.

    Is it good idea to have mainwindow to handle the UI, simple commander, block commanderand a device specific serial handler (using the QSerialPort)? Later on, the UI will be dropped and the rest is to be moved into a "subsystem" of a bigger whole.

    The mainwindow has slots of all "command sending" widgets (mostly buttons), and when a command is sent, it gets that data from other fields (command parameters) and sends the bunch to the appropriate commander, that handle the command and "code" them using the device specific serial handler.

    The mainwindow has "command signals" and "response slots" and so do the command handlers and the device specific serial handler.

    The mainwindow ties the "command signals" and "response slots" together, except that the device specific serial handler connects its "command signals" and "response slots" with the QSerialPort stuff.

    Is that an OK structure? Am I overusing/underusing signals/slots?

    How about handling ACK-messages? Those can come for both simple and multiblock commands. Is it better to use a flag for routing the ACK to the appropriate commander, or is re-connecting signals/slots between the device specific serial handler and the appropriate commander a preferred way?


  • Moderators

    It sounds like your main window is being used for rapid prototyping, so having it handle the commanders/serial handler is fine. It's faster to manipulate code this way.

    If it were a permanent of the system though, I'd separate the UI from the commanders/handler, and have them communicate via signals+slots without being made aware of each others' existence.

    [quote]The mainwindow has slots of all “command sending” widgets (mostly buttons), and when a command is sent, it gets that data from other fields (command parameters) and sends the bunch to the appropriate commander[/quote]Just to check that I've understood your description correctly. Did you mean this sequence?:

    Your window's slot reads the input data fields

    It packages the data

    It emits the data in a signal

    The signal parameters "enter" the relevant commander slot

    If so, then you already have good separation between your UI and your workers. That's a good use of signals+slots.

    [quote]How about handling ACK-messages? Those can come for both simple and multiblock commands. Is it better to use a flag for routing the ACK to the appropriate commander, or is re-connecting signals/slots between the device specific serial handler and the appropriate commander a preferred way?[/quote]I would have one class monitor the serial port for incoming messages. When it receives one, it decodes it, and...

    • Either call the relevant handler function directly, or
    • Send the decoded message the relevant handler class through a signal


  • bq. Just to check that I’ve understood your description correctly. Did you mean this sequence?:
    Your window’s slot reads the input data fields
    It packages the data
    It emits the data in a signal
    The signal parameters “enter” the relevant commander slot

    Yes.

    Also the clicks and selections (combobox) come to the main window slots as signals, but the textbox stuff is just read from the ui.
    I wonder if that's overdoing/underdoing it?

    bq. I would have one class monitor the serial port for incoming messages. When it receives one, it decodes it, and…
    Either call the relevant handler function directly, or
    Send the decoded message the relevant handler class through a signal

    That spells:
    "use a flag for routing the ACK to the appropriate commander"

    Lots of thanks!
    I guess when I get further I'll stuff my question heap into a new thread.

    How do I mark the problem solved, and is there a way to give points to answerers?


  • Moderators

    [quote author="turboscrew" date="1381936192"]Also the clicks and selections (combobox) come to the main window slots as signals, but the textbox stuff is just read from the ui.
    I wonder if that's overdoing/underdoing it?[/quote]A bit hard to tell from descriptions alone. Can you share your main window code?

    [quote]Lots of thanks!
    I guess when I get further I'll stuff my question heap into a new thread.

    How do I mark the problem solved, and is there a way to give points to answerers?[/quote]You're welcome :)

    The common way is to edit your original post and add "[SOLVED]" to your title. This forum doesn't support identification of answers or up/downrating of individual posts/posters (yet?), unfortunately.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.