Well, it's more extensive in the sense of requiring changes to the code you've written here, but it will make things a lot simpler overall.  One of the things that make QThreads convenient is that they have event loops, and support asynchronous method calls.  In other words, rather than having an explicit queue of messages as you've set up here, you can let Qt do the work for you.  Let's say you have a QObject with a method handleMessage(QHostAddress address, QByteArray data), declared with the Q_INVOKABLE macro so that's exposed to the metaobject system and thus dynamically invokable.

When you get the message from the network, you invoke the method dynamically: QMetaObject::invokeMethod(object, "handleMessage", Q_ARG(QHostAddress, address), Q_ARG(QByteArray, data)).  If "object" has the thread affinity of the current thread, that just performs a normal method call.  If, however, you create an instance of QThread, start it up, and push "object" to it using setThread, the method's arguments will be marshalled, and the call will be queued up and run on the thread that you've created.  In other words, most of the stuff you've added here is a process that Qt supports in a very streamlined and generic way.