Qt 槽调用两次
Qt slot invokes twice
在 mainwindow
中有一个插槽 MainWindow::establish_connection
,我试图在其中调用不同线程中的 Server::establish_connection
:
void MainWindow::establish_connection(const std::string& nickname,
const std::string& ip, int port)
{
auto thread = new QThread(this);
remote_server = new Server(nickname, ip, port);
connect(thread, SIGNAL(started()), remote_server, SLOT(establish_connection()));
connect(remote_server, SIGNAL(connected()), this, SLOT(connection_established()));
connect(remote_server, SIGNAL(readyRead()), this, SLOT(handle_reply()));
connect(remote_server, SIGNAL(error(QAbstractSocket::SocketError)), this,
SLOT(connection_failed(QAbstractSocket::SocketError)));
connect(remote_server, SIGNAL(stop_thread()), thread, SLOT(quit()));
thread->start();
}
Server::establish_connection
方法:
void Server::establish_connection()
{
master_socket = std::move(
std::unique_ptr<QTcpSocket>(new QTcpSocket(nullptr)));
connect(master_socket.get(), SIGNAL(connected()), SIGNAL(connected()));
connect(master_socket.get(), SIGNAL(readyRead()), SIGNAL(readyRead()));
connect(master_socket.get(), SIGNAL(error(QAbstractSocket::SocketError)),
SIGNAL(error(QAbstractSocket::SocketError)));
master_socket->connectToHost(ip.c_str(), port);
if (!master_socket->waitForConnected(timeout*1000))
{
emit error(master_socket->error());
}
emit stop_thread();
}
但是当 error
信号发出时,MainWindow::connection_failed
调用两次。
void MainWindow::connection_failed(QAbstractSocket::SocketError e)
{
QString err_msg = remote_server->get_socket()->errorString();
qDebug() << err_msg;
}
输出:
"Connection refused"
"Connection refused"
如何防止这个问题?
这里你重新发出来自 master_socket 的信号错误:connect(master_socket.get(), SIGNAL(error(QAbstractSocket::SocketError)),
SIGNAL(error(QAbstractSocket::SocketError)));
这对我来说似乎是第一。
这里你在超时后自己发出:
if (!master_socket->waitForConnected(timeout*1000))
{
emit error(master_socket->error());
}
这似乎是你的第二名。
我认为当您等待超时 error()
时,它已经被您的 connect()
发出并转发。之后你又自己发射它。这个好像超级流畅
测试删除此显式发出是否对您有用。
或者,您可以将行 connect(master_socket.get(), SIGNAL(error(QAbstractSocket::SocketError)),
SIGNAL(error(QAbstractSocket::SocketError)));
放在 if
条件之后,以获取从该点开始的所有错误。无需断开连接。
或者将其放在 else
分支中,因为您只对可以建立连接的任何更多错误感兴趣:
if (!master_socket->waitForConnected(timeout*1000))
{
emit error(master_socket->error());
} else {
connect(master_socket.get(), SIGNAL(error(QAbstractSocket::SocketError)),
SIGNAL(error(QAbstractSocket::SocketError)));
}
两者都应该有效。
在 mainwindow
中有一个插槽 MainWindow::establish_connection
,我试图在其中调用不同线程中的 Server::establish_connection
:
void MainWindow::establish_connection(const std::string& nickname,
const std::string& ip, int port)
{
auto thread = new QThread(this);
remote_server = new Server(nickname, ip, port);
connect(thread, SIGNAL(started()), remote_server, SLOT(establish_connection()));
connect(remote_server, SIGNAL(connected()), this, SLOT(connection_established()));
connect(remote_server, SIGNAL(readyRead()), this, SLOT(handle_reply()));
connect(remote_server, SIGNAL(error(QAbstractSocket::SocketError)), this,
SLOT(connection_failed(QAbstractSocket::SocketError)));
connect(remote_server, SIGNAL(stop_thread()), thread, SLOT(quit()));
thread->start();
}
Server::establish_connection
方法:
void Server::establish_connection()
{
master_socket = std::move(
std::unique_ptr<QTcpSocket>(new QTcpSocket(nullptr)));
connect(master_socket.get(), SIGNAL(connected()), SIGNAL(connected()));
connect(master_socket.get(), SIGNAL(readyRead()), SIGNAL(readyRead()));
connect(master_socket.get(), SIGNAL(error(QAbstractSocket::SocketError)),
SIGNAL(error(QAbstractSocket::SocketError)));
master_socket->connectToHost(ip.c_str(), port);
if (!master_socket->waitForConnected(timeout*1000))
{
emit error(master_socket->error());
}
emit stop_thread();
}
但是当 error
信号发出时,MainWindow::connection_failed
调用两次。
void MainWindow::connection_failed(QAbstractSocket::SocketError e)
{
QString err_msg = remote_server->get_socket()->errorString();
qDebug() << err_msg;
}
输出:
"Connection refused"
"Connection refused"
如何防止这个问题?
这里你重新发出来自 master_socket 的信号错误:connect(master_socket.get(), SIGNAL(error(QAbstractSocket::SocketError)),
SIGNAL(error(QAbstractSocket::SocketError)));
这对我来说似乎是第一。
这里你在超时后自己发出:
if (!master_socket->waitForConnected(timeout*1000))
{
emit error(master_socket->error());
}
这似乎是你的第二名。
我认为当您等待超时 error()
时,它已经被您的 connect()
发出并转发。之后你又自己发射它。这个好像超级流畅
测试删除此显式发出是否对您有用。
或者,您可以将行 connect(master_socket.get(), SIGNAL(error(QAbstractSocket::SocketError)),
SIGNAL(error(QAbstractSocket::SocketError)));
放在 if
条件之后,以获取从该点开始的所有错误。无需断开连接。
或者将其放在 else
分支中,因为您只对可以建立连接的任何更多错误感兴趣:
if (!master_socket->waitForConnected(timeout*1000))
{
emit error(master_socket->error());
} else {
connect(master_socket.get(), SIGNAL(error(QAbstractSocket::SocketError)),
SIGNAL(error(QAbstractSocket::SocketError)));
}
两者都应该有效。