Qt C ++的“新”操作可能会导致意外错误?

时间:2018-06-24 13:56:13

标签: c++ qt oop

我的项目中有两个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()中填充数据)。 我尝试了很长时间的网上搜索,但没有任何结果。
如果您能给我任何想法,我将不胜感激。
预先感谢。

2 个答案:

答案 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中进行自动完成,我能够重现错误的自动完成:

enter image description here

最后但并非最不重要的一点是,您确实需要照顾其余的代码。另外,我还建议在创建连接时使用新的信号插槽语法。它允许正确的类型检查(旧的SIGNAL()SLOT()不提供这种检查,因为您只是将字符串作为参数传递)。