我的项目中有两个UI,分别是Login和MainWindow。
现在,我使用信号插槽方法将Login的一些数据传输到一些MainWindow类成员变量,这是一些关键代码:
Login::Login(QWidget *parent)
: QDialog(parent)
{
setupUi(this);
MainWindow *w = new MainWindow;
connect(this,SIGNAL(sendData(QList<QString>)),w,SLOT(receiveData(QList<QString>)));
}
//get data from Login
void MainWindow::receiveData(QList<QString> userList){
userName = userList.at(0);
password = userList.at(1);
QSqlQuery query;
bool b = query.exec(QString("SELECT * FROM user WHERE user_id = '%1' AND password = '%2'").arg(userName).arg(password));
if(b){
query.first();
userType = query.value(1).toString();
qDebug()<<"user_type:"<<userType; //always has value in userType
qDebug()<<"user_id:"<<userName; //always has value in userName
}
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
public:
QString userName; //member variables declared here.
QString password;
QString userType;
我试图在main函数而不是Login构造函数中连接信号和插槽:
int main(int argc, char *argv[]) {
QApplication a(argc, argv);
...
MainWindow w;
Login l;
connect(&l,SIGNAL(sendData(QList<QString>)),&w,SLOT(receiveData(QList<QString>)));
if(l.exec() == QDialog::Accepted){
w.show();
}
return a.exec();
}
,但具有以下错误信息:
D:\QtProject\TMS\main.cpp:416: error: invalid conversion from 'Login*' to 'SOCKET {aka unsigned int}' [-fpermissive]
connect(&l,SIGNAL(sendData(QList<QString>)),&w,SLOT(receiveData(QList<QString>)));
D:\QtProject\TMS\main.cpp:416: error: cannot convert 'const char*' to 'const sockaddr*' for argument '2' to 'int connect(SOCKET, const sockaddr*, int)'
现在,真正让我困惑的是,当我在其他MainWindow函数中使用它们时,为什么userName或userType的值为空(已在函数receiveData()中填充数据)。
我尝试了很长时间的网上搜索,但没有任何结果。
如果您能给我任何想法,我将不胜感激。
预先感谢。
答案 0 :(得分:3)
您在main()
函数中尝试过的方法是正确的方法。您需要更改的内容:
connect()
中的 main()
必须为QObject::connect()
–这是QObject
类的静态成员函数。如果您是从QObject
派生的类的实现内部进行调用的,则无需限定该调用,因为编译器默认会选择正确的函数。 main()
并非如此。从编译器错误中可以推断出编译器选择了一个完全不相关的connect()
函数。
Login
的构造函数实例化其他 MainWindow
对象并连接到其插槽。那不是你想要的您要使用现有的主窗口对象– w
。从Login::Login()
删除 new 和 connect 行。它们是多余的。
在main()
中将return a.exec()
移到if
中。否则,当不接受登录对话框时,您的程序将不会显示主窗口,但也不会终止。 QApplication::exec()
启动主GUI事件循环。简而言之:在用户决定关闭程序之前,这就是使主窗口保持活动状态的原因。如果在不显示主窗口的情况下开始循环,则除了终止进程外,没有其他方法可以结束程序。您希望您的main()
看起来像这样:
int main(int argc, char* argv[])
{
QApplication app(argc, argv);
MainWindow mainWin;
Login loginDialog;
// ... connect and any other setup stuff
if (loginDialog.exec() == QDialog::Accepted) {
mainWin.show();
return app.exec();
}
return 1;
}
P.S。避免使用一个字母的变量名。没有有用的名称,您的程序将很快变得不可读。
答案 1 :(得分:1)
错误消息指出了问题的根源:
error: cannot convert 'const char*' to 'const sockaddr*' for argument '2' to 'int connect(SOCKET, const sockaddr*, int)'
您正在调用完全不同的connect()
函数,而不是QObject::connect()
(请注意,在QObject
前面使用connect()
-这是非常重要的,因为它是静态方法)。 sockaddr
表示您正在尝试使用
int connect(int socket, const struct sockaddr *address, size_t address_len);
来自#include <sys/socket.h>
,这显然是错误的。也许您添加了一个标头,当执行自动完成时,该标头替换了QObject::connect()
。我建议您仔细检查编辑器给您的建议,并检查某处的socket.h
标头。
通过将#include <sys/socket.h>
添加到小型Qt应用程序并尝试在同一源文件中的Qt Creator中进行自动完成,我能够重现错误的自动完成:
最后但并非最不重要的一点是,您确实需要照顾其余的代码。另外,我还建议在创建连接时使用新的信号插槽语法。它允许正确的类型检查(旧的SIGNAL()
和SLOT()
不提供这种检查,因为您只是将字符串作为参数传递)。