[solved]Combining two classes



  • Hi,

    First of all, I am a beginner in the QT word so sorry if what I wrote is bad.
    I would like to create a directory at the beginning of the application. The directory name can vary

    depending on the situation.
    Then I would like to save future files created in a class named fenetre into this directory.
    For that:
    I create a Class named CreateDirectory , Its constructor creates the directory that will be used

    later and a parameter of this class (QString repertoire) contains the directory name.
    I create a class named fenetre and declare 'friend class CreateDirectory;' in its header.

    I create an objet of the class CreateDirectory named rep in the main.cpp And create a class-fenetre

    objet with rep as an argument .

    Please find below what I have done so far.
    Clicking the button 'next' has no effect.

    Could you help me out with this problem.
    Thank you in advance.

    @
    //main.cpp
    int main(int argc, char *argv[])
    {
    QApplication a(argc, argv);
    CreateDirectory *rep= new CreateDirectory;
    rep->show();

    fenetre h(rep);
    h.show();
    return a.exec();
    

    }
    @

    @
    //CreateDirectory.cpp
    CreateDirectory::CreateDirectory(){
    int n=1;
    QDir lDir;
    QString dossier="repertoire";

    while (true){
    dossier = "repertoire"+ qApp->tr("-%1").arg(n);
    if ( !lDir.exists ( dossier ))
    {
    lDir.mkdir(dossier);
    break;
    }
    else
    n += 1;
    }
    //-----------------------

    repertoire=dossier+"\";

    }
    @

    @
    fenetre::fenetre(CreateDirectory *rep){

    DirectoryDeTravail=rep.repertoire;
    
    
    QPushButton *quitter= new QPushButton("Quitter", this);
    connect(quitter,SIGNAL(clicked()),qApp,SLOT(quit()));
    
    QPushButton *next= new QPushButton("Next", this);
    connect(next,SIGNAL(clicked( CreateDirectory,QLineEdit 
    

    )),this,SLOT(monslot(CreateDirectory,QLineEdit)));

    line= new QLineEdit(this);  // a number
    

    }
    @

    @
    void fenetre::monslot(CreateDirectory *rep, QlineEdit * line)
    {
    this->hide();
    QFile output(QString("%1/nom%2.txt").arg(DirectoryDeTravail).arg(line->text()));

    fenetre h(rep);
    h->show();
    }
    @


  • Moderators

    Hi, welcome to Qt :) (by the way, the name is "Qt". "QT" is QuickTime)

    Your main problem is here:
    [quote]
    @
    QPushButton *next= new QPushButton("Next", this);
    connect(next,SIGNAL(clicked( CreateDirectory,QLineEdit

    )),this,SLOT(monslot(CreateDirectory,QLineEdit)));
    @
    [/quote]Signals are functions, so you must follow the function prototype.

    The function prototype for that signal is "void QPushButton::clicked(bool checked = false);":http://qt-project.org/doc/qt-5.0/qtwidgets/qabstractbutton.html#clicked -- it can only take a boolean argument, or no arguments.

    So, you cannot write SIGNAL (clicked(CreateDirectory, QLineEdit)) -- you can only write SIGNAL (clicked(bool)) or SIGNAL (clicked()).

    You can store the CreateDirectory pointer in your fenetre object, and make fenetre::monslot() take no arguments:

    @
    fenetre::fenetre(CreateDirectory *rep) {
    this->rep = rep;
    this->line = new QLineEdit(this);
    ...
    connect(next, SIGNAL(clicked()), this, SLOT(monslot()));
    }

    void fenetre::monslot()
    {
    this->hide();
    QFile output(QString("%1/nom%2.txt").arg(DirectoryDeTravail).arg(this->line->text()));
    ...
    }
    @

    ======================
    There are also a few other problems:

    [quote]
    @
    repertoire=dossier+"\";
    @
    [/quote]Qt uses '/' for file and directory paths, even in Windows. For example, you should write "C:/MyFolder/MySubfolder/"

    [quote]
    @
    void fenetre::monslot(CreateDirectory *rep, QlineEdit * line)
    {
    this->hide();

    ... 
    fenetre h(rep);
    h->show();
    

    }
    @
    [/quote]Is the new fenetre created on the heap or the stack?

    If you use the stack (fenetre h(rep)), it will be destroyed when monslot() returns. If you use the heap (fenetre *h = new fenetre(rep)), the first fenetre still exists, and you have a memory leak.


  • Lifetime Qt Champion

    Hi,

    You're connect statement won't work because QPushButton doesn't have a signal called clicked(CreateDirectory, QLineEdit). There should also be a warning in the console telling you that there is something wrong.

    Please, have a look at the Qt's example, go through the basics first to create your widgets and signal/slots interaction. It will be then easier to include your business logic.



  • Hi, Thank you for your help.
    It works great.

    1)Nevertheless I had to erase the instruction about the destructor in fenetre.h.
    // ~fenetre();
    What can I do to keep a destructor declaration in the fenetre header?

    2)in monslot(), since this.hide doesn't kill the object, may I use 'this.destroy' before creating the new fenetre-class object?
    @
    this.destroy;
    fenetre *h = new fenetre(rep);
    h->setGeometry(00,100,300,300);
    h->show();
    @

    3)After creating the files named nom1 (nom2,...) I would like to add the instructions below:
    Is this bit of code acceptable?

         @
         bool ok = output.open(QFile::WriteOnly|QFile::Text);
         if (ok)
          {
        
          QTextStream stream(&output);
             stream.setIntegerBase(10);
            stream.setCodec("UTF-8");
             stream << "info: " << line->text() << "\n\n";
             stream << "info2 " << line2->text() << "\n\n";
              stream.flush();
            output.close();
             }
             else
            {
              qDebug("Impossible d'ouvrir le fichier txt");
             }
    
          @
    
    4) In fact I would like to create a html file. Can I keep the above code?      

  • Moderators

    [quote author="phil63" date="1371230754"]1)Nevertheless I had to erase the instruction about the destructor in fenetre.h.
    // ~fenetre();[/quote]Why?

    [quote]2)in monslot(), since this.hide doesn't kill the object, may I use 'this.destroy' before creating the new fenetre-class object?
    @
    this.destroy;
    fenetre *h = new fenetre(rep);
    h->setGeometry(00,100,300,300);
    h->show();
    @
    [/quote]A few things small things first:

    There is no destroy() function, only deleteLater().

    "this" is a pointer, you'll need to write "this->function()", not "this.function()"

    But more importantly, there's no need to create a new one and delete the old one. Just update the old one.

    [quote]3)After creating the files named nom1 (nom2,...) I would like to add the instructions below:
    Is this bit of code acceptable?

         @
         bool ok = output.open(QFile::WriteOnly|QFile::Text);
         if (ok)
          {
        
          QTextStream stream(&output);
             stream.setIntegerBase(10);
            stream.setCodec("UTF-8");
             stream << "info: " << line->text() << "\n\n";
             stream << "info2 " << line2->text() << "\n\n";
              stream.flush();
            output.close();
             }
             else
            {
              qDebug("Impossible d'ouvrir le fichier txt");
             }
    
          @
    

    [/quote]That looks fine. Since you already wrote the code, you can test it yourself -- it's faster than asking here :)

    [quote]4) In fact I would like to create a html file. Can I keep the above code?[/quote]Yes, but you need to write extra code to convert your input text into a HTML document (for example, adding tags like <html></html>, <body></body>, etc.)



  • Hi, Thank you for your reply.
    About the destructor : I inadvertantly discarded the instruction fenetre::~fenetre() in fenetre.cpp and this mistake was at the origin of the error message I had.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.