First, what is wrong with your code:
You cannot use this
in new QTcpSocket(this)
, because this->thread()
is not the current thread (QThread::currentThread()
).
You cannot call any function member of socket
after socket->moveToThread(this->thread())
, because socket->thead()
is not the current thread anymore.
This is documented here:
Event driven objects may only be used in a single thread.
Specifically, this applies to the timer mechanism and the network
module. For example, you cannot start a timer or connect a socket in a
thread that is not the object's thread.
Now, what you can do to fix your code if you just want to connect a TCP socket and do nothing more is to remove any reference to this
and do something like that:
void MainWindow::checkCamStatus(){
while(1){
bool flag = false;
QScopedPointer<QTcpSocket> socket(new QTcpSocket());
socket->connectToHost("10.0.7.112", 80);
if(socket->waitForConnected(1000))//check for connection for i second
{
qDebug() << "Cam online";
}
else{
qDebug() << "..............................Cam offline";
}
QThread::sleep(1);
}
}
But, if you want to do something else with the TCP socket like sending or receiving data, you'd be better wrapping up your code in a class:
class CamWatcher : public QObject
{
Q_OBJECT
public:
CamWatcher(QObject *parent = 0) :
QObject(parent),
m_socket(new QTcpSocket(this))
{}
QTcpSocket *socket() { return m_socket; }
public slots:
void tryConnect() { socket->connectToHost("10.0.7.112", 80); }
private slots:
void onSocketConnected() { qDebug() << "Connected"; }
void onSocketDisconnected() { qDebug() << "Disconnected"; }
void onSocketError(QAbstractSocket::SocketError socketError)
{
qWarning() << m_socket->errorString();
}
private:
QTcpSocket *m_socket = nullptr;
}
This way you can have all the TCP stuff (monitoring, data transfer, etc.) ins a single object. You can have it in the same thread than your MainWindow, but you can also have it in another thread if needed.
Note that if you have the CamWatcher in another thread than MainWindow, but you want to call functions of CamWatcher you have to do something like this:
QTimer::singleshot(0, camwatcher, &CamWatcher::tryConnect);
QMetaObject::invokeMethod(camwatcher, "tryConnect", Qt::QueuedConnection); // No compile time check, works only with slots
QMetaObject::invokeMethod(camwatcher, &CamWatcher::tryConnect, Qt::QueuedConnection); // Requires Qt 5.10