问题
I need your advice on a program I'm coding right now. Let me first present you what it is.
Design
I'm designing a man-machine interface (MMI). In this MMI, there are two core elements:
The
MainWindow
:
This MainWindow is the base of everything. Important: Here, I launch in a thread a server
that receives the data from a client. This data is very important to the next element.
Supervision
This window contains a QTableWidget
, the goal is to show in pseudo-real time the data received on the server in the thread of MainWindow.
The Problem
The server in the thread owned by the MainWindow
receive a structure every 10 mS. How can I send these data to the Supervision
window if it's open? I was thinking of using shared memory, but not really sure about this, and doesn't really which method I have to use.
Some Solutions
I tried to implement the solution of Sebastian Lange :
- An emit in the thread Server
- A connect in the MainWindow
- A slot in supervision
So now my thread Server
emit a signal at every frame received. But how can I do the connect in the MainWindow and how will Supervision
receive the struct emit
in the signal?
Here's the code of my emit:
MainWindow* MainWindow::m_psMainWindow = nullptr; // C++ 11 nullptr
void MainWindow::emit_signal_TrameRecu(StructureSupervision::T_StructureSupervision* ptr){
emit signal_TrameRecu(ptr);
}
void MainWindow::lancerServeur(std::atomic<bool>& boolServer){
serveur s;
StructureSupervision::T_StructureSupervision* bufferStructureRecu;
while(boolServer){
bufferStructureRecu = s.receiveDataUDP();
if(bufferStructureRecu->SystemData._statutGroundFlight != 0){
m_psMainWindow->emit_signal_TrameRecu( bufferStructureRecu );
}
}
}
回答1:
Queued Connections
Qt makes cross thread communication easy when you use queued connections.
Your calls to connect
should use the Qt::QueuedConnection or Qt::BlockingQueuedConnection connection types.
Custom Types in Slots and Signals
To use custom types (structs) in slots, signals, QVariant and properties you need to declare and register the type to make it available to the Qt dynamic type system.
In your header (.hpp) use Q_DECLARE_METATYPE and in your source (.cpp) use qRegisterMetaType.
Worked Example
server.hpp
#ifndef SERVER_HPP
#define SERVER_HPP
#include <QtCore>
struct customdata
{
int id;
QDateTime tstamp;
};
Q_DECLARE_METATYPE(customdata)
class Server : public QThread
{
Q_OBJECT
public:
Server();
signals:
void sendData(const customdata& d);
protected:
virtual void run();
};
#endif
server.cpp
#include "server.hpp"
static const int customdata_metatype_id =
qRegisterMetaType<customdata>();
Server::Server() : QThread() {}
void Server::run()
{
customdata d;
d.id = 0;
for (int i = 0; i < 10; ++i)
{
d.id++;
d.tstamp = QDateTime::currentDateTime();
emit sendData(d);
sleep(1);
}
}
window.hpp
#ifndef WINDOW_HPP
#define WINDOW_HPP
#include <QtGui>
#include "server.hpp"
class Window : public QWidget
{
Q_OBJECT
public:
Window();
public slots:
void receiveData(const customdata& d);
private:
QListWidget* mList;
};
#endif
window.cpp
#include "window.hpp"
Window::Window() : QWidget(),mList(new QListWidget())
{
resize(400, 300);
QVBoxLayout* mainLayout = new QVBoxLayout();
mainLayout->addWidget(mList);
setLayout(mainLayout);
}
void Window::receiveData(const customdata& d)
{
QString str(QString("%1 %2").arg(d.id).arg(d.tstamp.toString()));
mList->addItem(str);
}
main.cpp
#include <QtGui>
#include "server.hpp"
#include "window.hpp"
int main(int argc, char** argv)
{
QApplication app(argc, argv);
Window win;
Server ser;
QObject::connect(
&ser, SIGNAL(sendData(customdata)),
&win, SLOT(receiveData(customdata)),
Qt::QueuedConnection);
win.show();
ser.start();
return app.exec();
}
test.pro
TEMPLATE=app
QT=core gui
HEADERS=server.hpp window.hpp
SOURCES=main.cpp server.cpp window.cpp
回答2:
I once (in the days of Qt 3.2) implemented this cross thread communication using QApplication::postEvent
(now QCoreApplication::postEvent). However nowadays best practise is to use promises and futures to communicate asynchronously between threads. Promises and futures has become a part of recent C++ standard and the concepts are also implemented separately as part of Qt 5 Concurrent framework. See http://qt-project.org/doc/qt-5/qtconcurrent-index.html
来源:https://stackoverflow.com/questions/24446043/communication-between-a-server-thread-and-a-man-machine-interface-mmi