Qt C++ "new" operation may cause unexpected errors?

100 views Asked by At

There are two UIs in my project, namely, Login and MainWindow.
Now I use signal-slot method to transfer some data of Login to some MainWindow class member variables,and here is some key code:

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;

I tried to connect signal and slot in main function instead of Login constructor:

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();
}

but with the following bug information:

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)'

Now, What really confuses me is that why the value of userName or userType is empty(which has been populated with data in function receiveData()) when I use them in other MainWindow functions.
I have tried searching on net for a long time but without any result working.
If you can give me any idea, I will appreciate it a lot.
Thanks in advance.

2

There are 2 answers

1
besc On BEST ANSWER

What you tried in your main() function is the right way to go. What you need to change:

  • connect() in main() must be QObject::connect() – it’s a static member function of the QObject class. If you call it from inside the implementation of a class that derives from QObject you don’t need to qualify the call because the compiler picks the correct function by default. Not so in main(). From your compiler errors you can deduce that the compiler picked a completely unrelated connect() function.

  • The constructor of Login instantiates an additional MainWindow object and connects to its slot. That’s not what you want. You want to use the existing main window object – w. Delete the new and connect lines from Login::Login(). They are redundant.

  • In main() move return a.exec() into the if. Otherwise when the login dialog is not accepted your program does not show the main window, but it never terminates either. QApplication::exec() starts the main GUI event loop. In a very tiny nutshell: That is what keeps your main window alive until the user decides to close the program. If you start the loop without showing the main window then there is no way to end the program except for killing the process. You want your main() to look like this:

    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. Avoid one-letter variable names. Without useful names you programs become unreadable extremely quickly.

1
rbaleksandar On

The error message indicates the source of the problem:

error: cannot convert 'const char*' to 'const sockaddr*' for argument '2' to 'int connect(SOCKET, const sockaddr*, int)'

You are calling a completely different connect() function and not QObject::connect() (notice the use of QObject in front of the connect() - it's very important since it's a static method). The sockaddr indicates that you are trying to use the

int connect(int socket, const struct sockaddr *address, size_t address_len);

from #include <sys/socket.h>, which is clearly incorrect. Perhaps you have added a header that replaces the QObject::connect() when you do an autocomplete. I would suggest that you carefully check what your editor gives you as a suggestion and also check for the socket.h header somewhere.

I was able to reproduce an incorrect autocomplete by just adding the #include <sys/socket.h> to a small Qt application and attempting to do an autocomplete inside Qt Creator inside the same source file:

enter image description here

Last but not least you really need to take care of the rest of the code. In addition I would also suggest using the new signal-slot syntax when creating a connection. It allows proper typechecking (the old SIGNAL() and SLOT() do not offer that since you just pass a string as argument).