我目前在Qt遇到一个奇怪的问题。 我有一个使用QTcpSocket处理多个客户端的应用程序。 客户端向服务器提供登录详细信息,服务器正在检查MySQL数据库以验证单独线程上的凭据。
我有2个不同的客户端程序登录到此服务器 1.一个使用Qt连接的简单客户端 2.用C-Sharp(.net)
编码的客户端然而
当第二个客户端尝试登录服务器时,我在服务器上收到错误告诉我:
QObject:无法为位于其他线程中的父级创建子级。父是QNativeSocketEngine(0x1231e00),父亲的线程是 QThread(0xc625f0),当前线程是CMySQLHandler(0xc67188)
我猜这是在MySQL处理程序线程上发生的 但奇怪的是,它在Qt
中编码的客户端上根本没有发生这是代码:
void CMySQLHandler::onAuthRequest(ulong clientID, QString email, QString psw, QString HWID, QString ip)
{
string pass = "", salt = "", name = "", avatar = "";
uint UserID = 0;
CUserData *extra = new CUserData();
bool success = false;
QString failReason = "Success";
string Query = "SELECT password, username, avatar, userid FROM jos_users LEFT JOIN jos_community_users ON jos_users.id = jos_community_users.userid WHERE email = '"+email.toStdString()+"'";
SQLRow Row = GetRow(Query);
if(!Row.empty())
{
QString hashedPass = QString(Row[0].c_str());
pass = hashedPass.split(':').at(0).toStdString();
salt = hashedPass.split(':').at(1).toStdString();
name = Row[1];
avatar = Row[2];
UserID = QString(Row[3].c_str()).toUInt();
QByteArray data;
data.append((psw + QString(salt.c_str())));
QString blah = QString(QCryptographicHash::hash(data,QCryptographicHash::Md5).toHex());
if(QString(pass.c_str()) == blah )
success = true;
else
failReason = "Invalid password";
}
else
{
failReason = "E-Mail not found";
emit Handle->onAuthCompleted(clientID, false, failReason, extra);
return;
}
extra->Avatar += avatar.c_str();
extra->UserID = UserID;
extra->Username = QString(name.c_str());
emit Handle->onAuthCompleted(clientID, true, QString(), extra);
}
这是信号定义
void CMySQLHandler :: onTimerInit()
{
//Authentication
connect(this, SIGNAL(doAuthCompleted(ulong,bool,QString,CUserData*)), Handle, SLOT(onAuthCompleted(ulong,bool,QString,CUserData*)));
connect(Handle, SIGNAL(doRequestAuth(ulong,QString,QString,QString,QString)), this, SLOT(onAuthRequest(ulong,QString,QString,QString,QString)));
//end
CMySQL::Init(Handle);
}
我是Qt框架的新手。 请原谅缺乏知识。
感谢您抽出宝贵时间阅读本文。
答案 0 :(得分:0)
Qt使用线程所有权对象的概念。线程自己的对象来做信号/插槽机制。问题是您正在尝试在Thread CMySQLHandler(0xc67188)中创建一个新对象,并为其分配父QNativeSocketEngine(0x1231e00)。但是QNativeSocketEngine归QThread(0xc625f0)所有,这是不允许的。我无法在代码中看到错误,因此您可能需要进行一些调试以找到导致错误的行并编辑您的问题。
答案 1 :(得分:0)
当您使用多个线程时,Qt会一直发生这种不同的线程问题。解决这个问题的规范方法是使用信号和插槽。
错误不会发生在onAuthRequest
中,可能更早,您尝试调用此函数。也许你在一个线程中创建一个CMySQLHandler
对象,并尝试在另一个线程中执行它的成员函数。
如果由于某种原因需要调用属于不同威胁的对象的函数,请在包含该函数的对象中创建slot
并使用emit
调用它。
查看类似问题QObject: Cannot create children for a parent that is in a different thread