Archief - [PROG]c++ / QT compile-probleem met QT

Het archief is een bevroren moment uit een vorige versie van dit forum, met andere regels en andere bazen. Deze posts weerspiegelen op geen enkele manier onze huidige ideeën, waarden of wereldbeelden en zijn op sommige plaatsen gecensureerd wegens ontoelaatbaar. Veel zijn in een andere tijdsgeest gemaakt, al dan niet ironisch - zoals in het ironische subforum Off-Topic - en zouden op dit moment niet meer gepost (mogen) worden. Toch bieden we dit archief nog graag aan als informatiedatabank en naslagwerk. Lees er hier meer over of start een gesprek met anderen.

Petrov

Legacy Member
hey allen, ben hier wat aan het testen met de QT libraries.
tot nu toe lukte alles, alles gecompileerd enzo. maar nu heb ik een eerste klasse gedefinieerd, ook geen probleem, maar wanneer ik een object van die klasse aanmaak krijg ik volgende compiler-fout:
Code:
Compiler: Default compiler
Bezig met uitvoeren van  make...
make.exe -f "Makefile" all
make.exe -f Makefile.Debug all

make.exe[1]: Entering directory `C:/tests/test1'
g++ -c -g -g -frtti -fexceptions -Wall -DUNICODE -DQT_LARGEFILE_SUPPORT -DQT_DLL -DQT_QT3SUPPORT_LIB -DQT3_SUPPORT -DQT_SQL_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_THREAD_SUPPORT -I"C:/QT/include/QtCore" -I"C:/QT/include/QtCore" -I"C:/QT/include/QtGui" -I"C:/QT/include/QtGui" -I"C:/QT/include/QtSql" -I"C:/QT/include/QtSql" -I"C:/QT/include/Qt3Support" -I"C:/QT/include/Qt3Support" -I"C:/QT/include" -I"." -I"C:/QT/include/ActiveQt" -I"debug" -I"." -I"..\..\QT\mkspecs\default" -o debug\main.o main.cpp

g++ -mthreads -Wl,-enable-stdcall-fixup -Wl,-enable-auto-import -Wl,-enable-runtime-pseudo-reloc -Wl,-subsystem,console -o "debug\test1.exe" debug\main.o  -L"c:\QT\lib" -lQt3Supportd4 -lQtSqld4 -lQtGuid4 -lQtCored4

debug\main.o(.text$_ZN5DbopsD1Ev[Dbops::~Dbops()]+0x3a): In function `ZN7QStringC1EPKc':
C:/QT/include/QtCore/../../src/corelib/arch/qatomic_windows.h: [COLOR="Yellow"]undefined reference to `vtable for Dbops'[/COLOR]
debug\main.o(.text$_ZN5DbopsC1Ev[Dbops::Dbops()]+0x56):C:/QT/include/QtCore/../../src/corelib/arch/qatomic_windows.h: [COLOR="Yellow"]undefined reference to `vtable for Dbops'[/COLOR]
collect2: ld returned 1 exit status

make.exe[1]: *** [debug\test1.exe] Error 1

make.exe[1]: Leaving directory `C:/tests/test1'

make.exe: *** [debug-all] Error 2

Uitvoering voltooid

Hier is de source van mijn progje:
Code:
    #include <iostream>
    #include <ostream>
    
    #include <QtSql>
    #include <QSqlDatabase>    
    #include <QApplication>
    #include <QPushbutton>
    #include <QFont>
    #include <QObject>
    
    #define HOSTN "127.0.0.1"
    #define DATABASEN "zaalbeheer"
    #define USERN "root"
    #define PASSW "root"
    #define PORT 3306
    
    using namespace std;

    class Dbops : public QObject
    {
          Q_OBJECT
          private:
                  QSqlDatabase db0;
                  bool oki;
          
          public:
                 Dbops()
                 {};
                 
          public slots:
                 void opendb()
                 {
                       db0 = QSqlDatabase::addDatabase("QMYSQL");  
                       db0.setHostName(HOSTN);
                       db0.setDatabaseName(DATABASEN);
                       db0.setUserName(USERN);
                       db0.setPassword(PASSW);
                       db0.setPort(PORT);
                       db0.open();
                 }
                 void closedb()
                 {
                      db0.close();
                 }
    };

    int main(int argc, char *argv[])
    {   
        QApplication a(argc, argv);
        QPushButton connect("connect",0);      
        Dbops dbops;
        connect.resize(75,30);
        connect.setFont(QFont("Times",18,QFont::Bold));
        
        QObject::connect(&connect,SIGNAL(clicked()),&connect,SLOT(quit()));
        
        a.setMainWidget(&connect);
        connect.show();
        return a.exec();  
    }

BuiZe

Legacy Member
  • test.cpp
    Code:
    #include <iostream>
    #include <ostream>
    
    #include <QtSql>
    #include <QSqlDatabase>    
    #include <QApplication>
    #include <QPushbutton>
    #include <QFont>
    #include <QObject>
    
    #include "Dbops.h"
    
    using namespace std;
    
    
    int main(int argc, char *argv[])
    {   
        QApplication a(argc, argv);
        QPushButton connect("connect",0);      
        Dbops dbops;
        connect.resize(75,30);
        connect.setFont(QFont("Times",18,QFont::Bold));
        
        QObject::connect(&connect,SIGNAL(clicked()),&connect,SLOT(quit()));
        
    //  a.setMainWidget(&connect);
        connect.show();
        return a.exec();  
    }
  • Dbops.h
    Code:
    #pragma once
    
    #include <QtSql>
    #include <QSqlDatabase>    
    #include <QObject>
    
    #define HOSTN "127.0.0.1"
    #define DATABASEN "zaalbeheer"
    #define USERN "root"
    #define PASSW "root"
    #define PORT 3306
    
    class Dbops : public QObject
    {
          Q_OBJECT
          private:
                  QSqlDatabase db0;
                  bool oki;
          
          public:
                 Dbops()
                 {};
                 
          public slots:
                 void opendb()
                 {
                       db0 = QSqlDatabase::addDatabase("QMYSQL");  
                       db0.setHostName(HOSTN);
                       db0.setDatabaseName(DATABASEN);
                       db0.setUserName(USERN);
                       db0.setPassword(PASSW);
                       db0.setPort(PORT);
                       db0.open();
                 }
                 void closedb()
                 {
                      db0.close();
                 }
    };
  • qmake -project
  • edit test.pro -> add
  • qmake
  • make
  • debug\test.exe
Als je QObject afleidt en de macro Q_OBJECT plaatst, moet dat in een headerfile gebeuren. Je kan QObject niet gebruiken als je een klasse ad-hoc gaat definieren. (Moet door de MetaObjectCompiler moc gehaald worden, zie Qt Assistant)

Verder moet in je Qt Project file staan dat je QtSql gaat gebruiken. setMainWidget is enkel voor portabiliteit met vorige versie 3 van Qt. Als je die wil gebruiken moet je ook QT += qt3support toevoegen aan je project file.

Petrov

Legacy Member
alvast bedankt, nu schijnt het wel te werken!

toch nog een klein vraagje:

wat doet "#pragma once"?

greetzz en merci

BuiZe

Legacy Member
Geen idee of het een Visual C++ only ding is, maar het is een aanduiding dat dit bestand slechts eenmaal mag geincludeerd worden bij het compileren, een kortere notatie dan het gebruikelijke
Code:
#ifndef HEADER_H
#define HEADER_H
...
#endif

wikipedia to the rescue:
Although #pragma once is not standard C/C++, enough compilers support it
http://en.wikipedia.org/wiki/Pragma_once

Petrov

Legacy Member
ok, thx
zit ondertussen met een volgend probleemke: na wat aanpassingen heb ik volgende code:

test.cpp:
Code:
#include <iostream>
#include <ostream>

#include <QtSql>
#include <QSqlDatabase>    
#include <QApplication>
#include <QPushbutton>
#include <QFont>
#include <QObject>

#include "Dbops.h"

using namespace std;


int main(int argc, char *argv[])
{   
    QApplication a(argc, argv); 
    QSqlDatabase db;   
    QWidget window;
    QPushButton connectButton("Connect",&window);  
    QPushButton disconnectButton("Disconnect",&window);   
    QPushButton quit("Quit",&window);
    
    Dbops DBobject;
    
    window.resize(200, 150);
    
    connectButton.setGeometry(5, 5, 180, 30);
    connectButton.setFont(QFont("Times",18,QFont::Bold));
    QObject::connect(&connectButton,SIGNAL(clicked()),&DBobject,SLOT(opendb(db)));
    
    disconnectButton.setGeometry(5,40,180, 30);
    disconnectButton.setFont(QFont("Times",18,QFont::Bold));
    QObject::connect(&disconnectButton,SIGNAL(clicked()),&DBobject,SLOT(closedb(db)));   
    
    quit.setGeometry(5,75,180, 30);
    quit.setFont(QFont("Times",18,QFont::Bold));
    QObject::connect(&quit,SIGNAL(clicked()),&a,SLOT(quit()));  
    
    window.show();
    return a.exec();  
}

Dbops.h:
Code:
#pragma once

#include <QtSql>
#include <QSqlDatabase>    
#include <QObject>
#include <iostream>
#include <ostream>

#define HOSTN "127.0.0.1"
#define DATABASEN "zaalbeheer"
#define USERN "root"
#define PASSW "root"
#define PORT 3306

using namespace std;

class Dbops : public QObject
{
      Q_OBJECT
      private:
              bool ok;
      
      public:
             Dbops()
             {};
             
      public slots:
             void opendb(QSqlDatabase db0)
             {
                   db0 = QSqlDatabase::addDatabase("QMYSQL");  
                   db0.setHostName(HOSTN);
                   db0.setDatabaseName(DATABASEN);
                   db0.setUserName(USERN);
                   db0.setPassword(PASSW);
                   db0.setPort(PORT);
                   ok = db0.open();
                   
                   if (ok == true)
                   {
                        cout << "Connected" << endl;;   
                   }
                   else
                   {
                       cout << "Connection Error" << endl;;
                   }
                   
             }
             void closedb(QSqlDatabase db0)
             {
                  db0.close();
                  cout << "Connection closed" << endl;; 
             }
};

compileren is geen probleem maar bij uitvoer krijg ik volgende boodschap:

Object::connect: no such slot Dbops::opendb(db)
Object::connect: no such slot Dbops::closedb(db)

any help pls?

BuiZe

Legacy Member
Wat je daar probeert is onmogelijk. Vooreerst moet je moet bij SLOT() het type meegeven (QSqlDatabase), niet een object (db).
Maar belangrijker is dat de signatuur van een signaal en een slot gelijk moeten zijn als je ze wil verbinden. Het signaal clicked() van een button zendt geen QSqlDatabase uit, dus kan je dat signaal niet binden aan een slot dat een QSqlDatabase als parameter nodig heeft.
(zie "Signals and Slots" in Qt Assistant)

Ik snap dat je gewoon de click-events wil opvangen en dan een stuk code uitvoeren naargelang op welke knop werd geklikt. Er is echter geen korte manier om dit te doen. Je bent nog best af met in de Qt Designer een venster met knoppen te tekenen, door de UserInterfaceCompiler (uic) te halen en dan via de "multiple inheritance" manier in je applicatie in te passen. Met gebruik van automatische connecties zal je zo het minste code moeten schrijven en je je op de database-kant van de zaak kunnen focussen.
(zie "Using a Component in Your Application" in Qt Assistant)

Petrov

Legacy Member
Ondertussen is het me gelukt met de designer een widget te maken en te displayen.
ik heb nu een ander klein probleem: op het form staan twee knoppen om met een db te verbinden en te disconnecten. wanneer ik connect, disconnect en opnieuw connect krijg ik volgende boodschap:
Code:
QSqlDatabasePrivate::addDatabase: duplicate connection name 'qt_sql_default_connection', old connection removed

Ik vermoed dat het probleem ligt bij het afsluiten van de database.
mijn close functie:

Code:
void Dbops::closedb()
{
     db.close();
     db.~QSqlDatabase();
     cout << "Connection closed" << endl;;
}

alvast merci

BuiZe

Legacy Member
Qt geeft enkel een warning, ik denk dat achter de schermen de aanroep removeDatabase() voor u gedaan wordt. Probeer anders dit eens:
Code:
void Dbops::closedb()
{
     QString name = db.databaseName();
     db.close();
     QSqlDatabase::removeDatabase(name); 
     cout << "Connection closed" << endl;
}

~QSqlDatabase() is een destructor en kan je zelf niet oproepen. Gaf je compiler hier geen warning op?

Petrov

Legacy Member
gaf geen warning nee, wat me zelf ook verbaasde

na aanpassing van de code krijg ik nu ook een foutmelding bij removeDatabase bij runnen van prog.

melding:
"QSqlDatabasePrivate::removeDatabase: connection 'qt_sql_default_connection' is still in use, all queries will cease working
QSqlDatabasePrivate::addDatabase: duplicate connection name 'qt_sql_default_connection', old connection removed"

header file van mijn class: Dbops.h
Code:
#pragma once

#include <QtSql>
#include <QSqlDatabase>    
#include <QObject>
#include <iostream>
#include <ostream>

#define HOSTN "127.0.0.1"
#define DATABASEN "zaalbeheer"
#define USERN "root"
#define PASSW "root"
#define PORT 3306

using namespace std;

class Dbops : public QObject
{
      Q_OBJECT
      private:
              QSqlDatabase db;
      
      public:
             Dbops()
             {};
             
      public slots:
             bool opendb();
             void closedb();
             bool execQuery(QString);
             
};

en van de class zelf, Dbops.cpp:
Code:
#include "Dbops.h"

bool Dbops::opendb()
{
     bool ok;
     //if db al open, foutmelding geven
     db = QSqlDatabase::addDatabase("QMYSQL");  
     db.setHostName(HOSTN);
     db.setDatabaseName(DATABASEN);
     db.setUserName(USERN);
     db.setPassword(PASSW);
     db.setPort(PORT);
     ok = db.open();
                   
     if (ok == true)
     {
      cout << "Connected" << endl;;   
     }
     else
     {
      cout << "Connection Error" << endl;;
     }
     return ok;     
}

void Dbops::closedb()
{
     QString name = db.databaseName();
     db.close();
     QSqlDatabase::removeDatabase(name); 
     cout << "Connection closed" << endl;
}

bool Dbops::execQuery(QString s)
{
     bool ok = false;
     QSqlQuery query("select max(kID) from klanten",db);
     QString msg;
     
     if ( query.isActive())
     {
          while(query.next())
          {
                msg = query.value(0).toString();                      
                cout << msg.toLatin1().data() << endl;                 
          }    
     }
     
     /*
     QSqlQuery query(s,db);
     
     if ( query.isActive() )
     {
        ok = query.exec();
     }   
     */
     
     return ok;
}
Het archief is een bevroren moment uit een vorige versie van dit forum, met andere regels en andere bazen. Deze posts weerspiegelen op geen enkele manier onze huidige ideeën, waarden of wereldbeelden en zijn op sommige plaatsen gecensureerd wegens ontoelaatbaar. Veel zijn in een andere tijdsgeest gemaakt, al dan niet ironisch - zoals in het ironische subforum Off-Topic - en zouden op dit moment niet meer gepost (mogen) worden. Toch bieden we dit archief nog graag aan als informatiedatabank en naslagwerk. Lees er hier meer over of start een gesprek met anderen.
Terug
Bovenaan