Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. How to call a variable defined in one function in another function

How to call a variable defined in one function in another function

Scheduled Pinned Locked Moved Unsolved General and Desktop
15 Posts 5 Posters 4.1k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • F Offline
    F Offline
    Fred Barclay
    wrote on 7 Sept 2016, 22:05 last edited by Fred Barclay 9 Jul 2016, 22:08
    #1

    (Apologies for non-correct terms. I'm not a C++ programmer) :-)

    I'm working on a GUI that will take a file chosen by the user and delete it using the srm command from the secure-delete package (on Linux). This is the code in Taz.cpp for the user to choose a file :

    void Taz::on_chooseButton_clicked()
    {
        QFileDialog dialog(this);
        dialog.setViewMode(QFileDialog::Detail);
        dialog.setFileMode(QFileDialog::ExistingFiles);
        QStringList fileNames;
        if (dialog.exec())
            fileNames = dialog.selectedFiles();
    }
    

    So if I understand this correctly, fileNames is the variabel referencing whatever file the user has chosen (or is this incorrect)?
    (NOTE: code for this taken from https://doc.qt.io/qt-5.7/qfiledialog.html)
    My goal for this is for the user to click the "Choose file" button that references the "onn_chooseButton_clicked() slot, which will open a file dialog from which he/she can select the file(s) to delete. If I understand the code correctly the list of files chosen is stored in the fileNames variable.

    Next, I want the user to press the "Shred" button, which will call the srm <chosen_files> command. This is where I'm having trouble. Obviously the files being deleted will be different every time, so I need a variable to substitute. Based on my understanding, I should be able to do something like srm fileNames to delete the file(s). However, I'm having a lot of trouble getting this to work. If I do

    void Taz::on_shredButton_clicked()
    {
        system(qPrintable("srm -r /home/fred/delete_me"))
    }
    

    the code will work perfectly and delete the file delete_me when I press the Shred button on the Gui. However, if I try to assign the fileNames variabel in place of the
    absolute path, I get nothing. I've tried various combinations such as
    system("srm " << fileNames.c_str());
    system(qPrintable("srm "<<fileNames));
    system(qPrintable("srm %s", fileName);
    or

       QProcess process;
        process.start("srm fileNames" );
    

    None of them will work.
    If I were in python I would say this is partly due because fileName is not a globally defined variable, but I can't see if that is the case here in C++/Qt.(That is, void signals a new function in C++, right?)

    Thanks for any help! I know my abysmal understanding of C++ is to blame, and I can't wait to get this behind me and start back work on my project. :-)

    1 Reply Last reply
    0
    • M Offline
      M Offline
      mrjj
      Lifetime Qt Champion
      wrote on 7 Sept 2016, 22:30 last edited by
      #2

      Hi and welcome

      From dialog you get a QStringList

      http://doc.qt.io/qt-5/qstringlist.html

      So you should loop it and call pr file

      for (int i = 0; i < fileNames.size(); ++i)
      cout << fileNames.at(i);

      It would be much better to use QProcess if possible.

      1 Reply Last reply
      0
      • F Offline
        F Offline
        Fred Barclay
        wrote on 7 Sept 2016, 22:53 last edited by Fred Barclay 9 Aug 2016, 00:15
        #3

        @mrjj Would this be correct?

        void Taz::on_chooseButton_clicked()
        {
            QFileDialog dialog(this);
            dialog.setViewMode(QFileDialog::Detail);
            dialog.setFileMode(QFileDialog::ExistingFiles);
            QStringList fileNames;
            if (dialog.exec())
                fileNames = dialog.selectedFiles();
            for (int i = 0; i < fileNames.size(); ++i)
                cout << fileNames.at(i);
        }
        

        ...

        void Taz::on_shredButton_clicked()
        {
             QProcess process;
            process.start("srm" <<cout );
        }
        

        Currently when I try to make this I get an error:

        g++ -c -pipe -O2 -std=gnu++0x -Wall -W -D_REENTRANT -fPIC -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -I. -I/opt/Qt/5.6/gcc_64/include -I/opt/Qt/5.6/gcc_64/include/QtWidgets -I/opt/Qt/5.6/gcc_64/include/QtGui -I/opt/Qt/5.6/gcc_64/include/QtCore -I. -I. -I/opt/Qt/5.6/gcc_64/mkspecs/linux-g++ -o taz.o taz.cpp
        taz.cpp: In member function ‘void Taz::on_chooseButton_clicked()’:
        taz.cpp:40:9: error: ‘cout’ was not declared in this scope
                 cout << fileNames.at(i);
                 ^
        Makefile:945: recipe for target 'taz.o' failed
        make: *** [taz.o] Error 1
        

        How should I declare cout?

        Thanks!

        J 1 Reply Last reply 8 Sept 2016, 00:00
        0
        • F Fred Barclay
          7 Sept 2016, 22:53

          @mrjj Would this be correct?

          void Taz::on_chooseButton_clicked()
          {
              QFileDialog dialog(this);
              dialog.setViewMode(QFileDialog::Detail);
              dialog.setFileMode(QFileDialog::ExistingFiles);
              QStringList fileNames;
              if (dialog.exec())
                  fileNames = dialog.selectedFiles();
              for (int i = 0; i < fileNames.size(); ++i)
                  cout << fileNames.at(i);
          }
          

          ...

          void Taz::on_shredButton_clicked()
          {
               QProcess process;
              process.start("srm" <<cout );
          }
          

          Currently when I try to make this I get an error:

          g++ -c -pipe -O2 -std=gnu++0x -Wall -W -D_REENTRANT -fPIC -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -I. -I/opt/Qt/5.6/gcc_64/include -I/opt/Qt/5.6/gcc_64/include/QtWidgets -I/opt/Qt/5.6/gcc_64/include/QtGui -I/opt/Qt/5.6/gcc_64/include/QtCore -I. -I. -I/opt/Qt/5.6/gcc_64/mkspecs/linux-g++ -o taz.o taz.cpp
          taz.cpp: In member function ‘void Taz::on_chooseButton_clicked()’:
          taz.cpp:40:9: error: ‘cout’ was not declared in this scope
                   cout << fileNames.at(i);
                   ^
          Makefile:945: recipe for target 'taz.o' failed
          make: *** [taz.o] Error 1
          

          How should I declare cout?

          Thanks!

          J Offline
          J Offline
          jeremy_k
          wrote on 8 Sept 2016, 00:00 last edited by
          #4

          @Fred-Barclay said in How to call a variable defined in one function in another function:

          taz.cpp: In member function ‘void Taz::on_chooseButton_clicked()’:
          taz.cpp:40:9: error: ‘cout’ was not declared in this scope
          cout << fileNames.at(i);
          ^
          Makefile:945: recipe for target 'taz.o' failed
          make: *** [taz.o] Error 1

          
          How should I declare cout?
          

          #include <iostream> and change the reference to std::cout to fix the error reported by the compiler, but that's not going to produce useful results. cout is an output file stream. cout << fileName.at(i) will write one file name at a time to standard output, without a newline or space to separate them. The commented-out process.start("srm" <<cout ) definitely isn't right.

          You may want to find a basic C++ tutorial such as http://www.cplusplus.com/doc/tutorial/classes/

          Asking a question about code? http://eel.is/iso-c++/testcase/

          F 1 Reply Last reply 8 Sept 2016, 00:12
          0
          • J jeremy_k
            8 Sept 2016, 00:00

            @Fred-Barclay said in How to call a variable defined in one function in another function:

            taz.cpp: In member function ‘void Taz::on_chooseButton_clicked()’:
            taz.cpp:40:9: error: ‘cout’ was not declared in this scope
            cout << fileNames.at(i);
            ^
            Makefile:945: recipe for target 'taz.o' failed
            make: *** [taz.o] Error 1

            
            How should I declare cout?
            

            #include <iostream> and change the reference to std::cout to fix the error reported by the compiler, but that's not going to produce useful results. cout is an output file stream. cout << fileName.at(i) will write one file name at a time to standard output, without a newline or space to separate them. The commented-out process.start("srm" <<cout ) definitely isn't right.

            You may want to find a basic C++ tutorial such as http://www.cplusplus.com/doc/tutorial/classes/

            F Offline
            F Offline
            Fred Barclay
            wrote on 8 Sept 2016, 00:12 last edited by Fred Barclay 9 Aug 2016, 00:15
            #5

            @jeremy_k Thanks - I'll read this more thoroughly in a moment, but the commented-out process.start("srm" <<cout ) is a typo. Fixing now. :)

            1 Reply Last reply
            0
            • M Offline
              M Offline
              mrjj
              Lifetime Qt Champion
              wrote on 8 Sept 2016, 06:03 last edited by mrjj 9 Aug 2016, 06:33
              #6

              hi
              Just a note:
              The arguments for QProcess should be put in a list

              //Example
              QString program = "./path/to/srm";
              QStringList arguments;
              arguments << "file1" << "file 2";
              QProcess myProcess(parent);
              myProcess.start(program, arguments);

              since fileNames is such list, you can use it directly.
              as in
              myProcess.start(program, fileNames );

              Also sorry for cout. what just to write out the names to check
              for (int i = 0; i < fileNames.size(); ++i)
              cout << fileNames.at(i); // <<< this prints the entry [i] from the list

              F 1 Reply Last reply 8 Sept 2016, 20:46
              2
              • M mrjj
                8 Sept 2016, 06:03

                hi
                Just a note:
                The arguments for QProcess should be put in a list

                //Example
                QString program = "./path/to/srm";
                QStringList arguments;
                arguments << "file1" << "file 2";
                QProcess myProcess(parent);
                myProcess.start(program, arguments);

                since fileNames is such list, you can use it directly.
                as in
                myProcess.start(program, fileNames );

                Also sorry for cout. what just to write out the names to check
                for (int i = 0; i < fileNames.size(); ++i)
                cout << fileNames.at(i); // <<< this prints the entry [i] from the list

                F Offline
                F Offline
                Fred Barclay
                wrote on 8 Sept 2016, 20:46 last edited by
                #7

                @mrjj Would this be correct? I'm just trying to get the contents of fileName echoed into a text file - before I try calling srm -r fileNames with another button.

                void Taz::on_chooseButton_clicked()
                {
                // New behavior
                    QFileDialog dialog(this);
                    dialog.setViewMode(QFileDialog::Detail);
                    dialog.setFileMode(QFileDialog::ExistingFiles);
                    QStringList fileNames;
                    if (dialog.exec())
                        fileNames = dialog.selectedFiles();
                
                    QObject *parent;
                    QString program = "/bin/echo";
                    QStringList arguments;
                    arguments << "fileNames" << ">> /home/fred/fn.txt";
                    QProcess *myProcess = new QProcess(parent);
                    myProcess->start(program, arguments);
                
                }
                

                When compiling with make I get a warning:

                taz.cpp: In member function ‘void Taz::on_chooseButton_clicked()’:
                taz.cpp:41:46: warning: ‘parent’ may be used uninitialized in this function [-Wmaybe-uninitialized]
                     QProcess *myProcess = new QProcess(parent);
                

                The GUI does finish compiling, though. However, nothing is echoed into /home/fred/fn.txt. :(
                Thanks!

                1 Reply Last reply
                0
                • M Offline
                  M Offline
                  mrjj
                  Lifetime Qt Champion
                  wrote on 8 Sept 2016, 20:56 last edited by
                  #8

                  Hi
                  well, this is not ok.
                  QObject *parent;
                  ..
                  QProcess *myProcess = new QProcess(parent);
                  as parent is a dangling pointer so its invalid to do.
                  ( its just points to random location)
                  ( that is what it means with warning: ‘parent’ may be used uninitialized)
                  so just use
                  QProcess *myProcess = new QProcess(this); // this being Taz ( mainwinow i guess)

                  also, you are not really processing the list
                  but you should get "fileNames" in the fn.txt?

                  maybe you can do
                  fileNames << ">> /home/fred/fn.txt";
                  and
                  myProcess->start(program, fileNames );

                  But in any case
                  "fileNames" do not expand to the real list as it would in say bash.
                  it just is text. like "hello".

                  F 1 Reply Last reply 8 Sept 2016, 21:14
                  0
                  • M mrjj
                    8 Sept 2016, 20:56

                    Hi
                    well, this is not ok.
                    QObject *parent;
                    ..
                    QProcess *myProcess = new QProcess(parent);
                    as parent is a dangling pointer so its invalid to do.
                    ( its just points to random location)
                    ( that is what it means with warning: ‘parent’ may be used uninitialized)
                    so just use
                    QProcess *myProcess = new QProcess(this); // this being Taz ( mainwinow i guess)

                    also, you are not really processing the list
                    but you should get "fileNames" in the fn.txt?

                    maybe you can do
                    fileNames << ">> /home/fred/fn.txt";
                    and
                    myProcess->start(program, fileNames );

                    But in any case
                    "fileNames" do not expand to the real list as it would in say bash.
                    it just is text. like "hello".

                    F Offline
                    F Offline
                    Fred Barclay
                    wrote on 8 Sept 2016, 21:14 last edited by
                    #9

                    @mrjj Thanks - unallocated error fixed. You're right, I'm definitely not processing the list fileNames. I was just hoping I could get something (even the word "fileNames") to be echoed into a file.

                    This yields nothing; is it what you are talking about?

                    void Taz::on_chooseButton_clicked()
                    {
                    // New behavior
                        QFileDialog dialog(this);
                        dialog.setViewMode(QFileDialog::Detail);
                        dialog.setFileMode(QFileDialog::ExistingFiles);
                        QStringList fileNames;
                        if (dialog.exec())
                            fileNames = dialog.selectedFiles();
                    
                        QString program = "/bin/echo";
                        QStringList arguments;
                        fileNames << ">> /home/fred/fn.txt";
                        QProcess *myProcess = new QProcess(this);
                        myProcess->start(program, fileNames );
                    }
                    

                    BTW: here is my entire taz.cpp file: https://gist.github.com/Fred-Barclay/f0454d31681fe3744659cd18dfd62403

                    and here is a screenshot (just in case...)
                    0_1473369253927_taz.png

                    1 Reply Last reply
                    0
                    • M Offline
                      M Offline
                      mrjj
                      Lifetime Qt Champion
                      wrote on 8 Sept 2016, 21:34 last edited by mrjj 9 Aug 2016, 21:35
                      #10

                      Hi
                      it looks ok now.

                      you should use qDebug() to check stuff out
                      (#include <QDebug>)

                      and do
                      qDebug() << " numfiles:" << fileNames.size();
                      It will show in Creator in output window.
                      Should give you a non zero value.

                      also
                      QProcess has a error() function u should also call to see if any errors.

                      for test u can also try
                      QProcess sh;
                      sh.start("sh", QStringList() << "-c" << "ifconfig" << ">> /home/fred/fn.txt");

                      1 Reply Last reply
                      0
                      • SGaistS Offline
                        SGaistS Offline
                        SGaist
                        Lifetime Qt Champion
                        wrote on 8 Sept 2016, 21:38 last edited by
                        #11

                        Hi,

                        IIRC, you should split >> and /home/fred/fn.txt and add both separately to your argument list.

                        Interested in AI ? www.idiap.ch
                        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                        F 1 Reply Last reply 8 Sept 2016, 21:46
                        0
                        • SGaistS SGaist
                          8 Sept 2016, 21:38

                          Hi,

                          IIRC, you should split >> and /home/fred/fn.txt and add both separately to your argument list.

                          F Offline
                          F Offline
                          Fred Barclay
                          wrote on 8 Sept 2016, 21:46 last edited by
                          #12

                          @SGaist Hmm... that would make sense but even then nothing seems to happen when or after I press the button ("Choose File" in the screenshot above):

                          void Taz::on_chooseButton_clicked()
                          {
                          // New behavior
                              QFileDialog dialog(this);
                              dialog.setViewMode(QFileDialog::Detail);
                              dialog.setFileMode(QFileDialog::ExistingFiles);
                              QStringList fileNames;
                              if (dialog.exec())
                                  fileNames = dialog.selectedFiles();
                          
                              QString program = "/bin/echo";
                              QStringList arguments;
                              arguments << "fileName" << ">>" << "/home/fred/fn.txt";
                              QProcess *myProcess = new QProcess(this);
                              myProcess->start(program, arguments);
                          }
                          
                          J 1 Reply Last reply 8 Sept 2016, 23:32
                          0
                          • SGaistS Offline
                            SGaistS Offline
                            SGaist
                            Lifetime Qt Champion
                            wrote on 8 Sept 2016, 21:49 last edited by
                            #13

                            You should add some error checking to your code. That would help pinpoint the problem.

                            Interested in AI ? www.idiap.ch
                            Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                            1 Reply Last reply
                            0
                            • F Fred Barclay
                              8 Sept 2016, 21:46

                              @SGaist Hmm... that would make sense but even then nothing seems to happen when or after I press the button ("Choose File" in the screenshot above):

                              void Taz::on_chooseButton_clicked()
                              {
                              // New behavior
                                  QFileDialog dialog(this);
                                  dialog.setViewMode(QFileDialog::Detail);
                                  dialog.setFileMode(QFileDialog::ExistingFiles);
                                  QStringList fileNames;
                                  if (dialog.exec())
                                      fileNames = dialog.selectedFiles();
                              
                                  QString program = "/bin/echo";
                                  QStringList arguments;
                                  arguments << "fileName" << ">>" << "/home/fred/fn.txt";
                                  QProcess *myProcess = new QProcess(this);
                                  myProcess->start(program, arguments);
                              }
                              
                              J Offline
                              J Offline
                              jeremy_k
                              wrote on 8 Sept 2016, 23:32 last edited by
                              #14

                              @Fred-Barclay said in How to call a variable defined in one function in another function:

                              @SGaist Hmm... that would make sense but even then nothing seems to happen when or after I press the button ("Choose File" in the screenshot above):

                              void Taz::on_chooseButton_clicked()
                              {
                              // New behavior
                                  QFileDialog dialog(this);
                                  dialog.setViewMode(QFileDialog::Detail);
                                  dialog.setFileMode(QFileDialog::ExistingFiles);
                                  QStringList fileNames;
                                  if (dialog.exec())
                                      fileNames = dialog.selectedFiles();
                              
                                  QString program = "/bin/echo";
                                  QStringList arguments;
                                  arguments << "fileName" << ">>" << "/home/fred/fn.txt";
                                  QProcess *myProcess = new QProcess(this);
                                  myProcess->start(program, arguments);
                              }
                              

                              Is the expectation that "fileName" will be appended to the file /home/fred/fn.txt?

                              Neither echo nor QProcess have special handling for ">>" as far as I am aware. Redirection to a file using this syntax is usually the domain of a shell such as bash. QProcess either redirects output to the enclosing program's output, or makes it available via QProcess::readChannel().

                              What you'll get instead is the string "fileName >> /home/fred/fn.txt" written to standard output.

                              #include <QCoreApplication>
                              #include <iostream>
                              #include <QProcess>
                              #include <QObject>
                              
                              int main(int argc, char *argv[])
                              {
                                  QCoreApplication a(argc, argv);
                                  QProcess p;
                                  p.setProcessChannelMode(QProcess::ForwardedChannels);
                                  QStringList arguments;
                                  arguments << "fileName" << ">>" << "/home/fred/fn.txt";
                                  QObject::connect<void(QProcess::*)(int)>(&p, &QProcess::finished, [=](){ std::cout << "process done" << std::endl; });
                                  p.start("/bin/echo", arguments);
                              
                                  return a.exec();
                              }
                              

                              Asking a question about code? http://eel.is/iso-c++/testcase/

                              1 Reply Last reply
                              0
                              • M Offline
                                M Offline
                                mjsurette
                                wrote on 9 Sept 2016, 01:10 last edited by mjsurette 9 Sept 2016, 01:15
                                #15

                                Hi. For a non c++ programmer, you seem to be catching on. Your posting of...

                                void Taz::on_chooseButton_clicked()
                                {
                                // New behavior
                                    QFileDialog dialog(this);
                                    dialog.setViewMode(QFileDialog::Detail);
                                    dialog.setFileMode(QFileDialog::ExistingFiles);
                                    QStringList fileNames;
                                    if (dialog.exec())
                                        fileNames = dialog.selectedFiles();
                                
                                    QString program = "/bin/echo";
                                    QStringList arguments;
                                    arguments << "fileName" << ">>" << "/home/fred/fn.txt";
                                    QProcess *myProcess = new QProcess(this);
                                    myProcess->start(program, arguments);
                                }
                                

                                isn't too bad. Just a little overly complex, so this

                                void Taz::on_chooseButton_clicked()
                                {
                                // New behavior
                                    QFileDialog dialog(this);
                                    dialog.setViewMode(QFileDialog::Detail);
                                    dialog.setFileMode(QFileDialog::ExistingFiles);
                                    QStringList fileNames;
                                    if (dialog.exec())
                                    {
                                        fileNames = dialog.selectedFiles();
                                        QProcess::execute("echo", fileNames);
                                    }
                                }
                                

                                should echo the filenames to your Application Output screen. This is actually a lot closer to what you're end game should look like.

                                HTH

                                Mike

                                1 Reply Last reply
                                0

                                1/15

                                7 Sept 2016, 22:05

                                • Login

                                • Login or register to search.
                                1 out of 15
                                • First post
                                  1/15
                                  Last post
                                0
                                • Categories
                                • Recent
                                • Tags
                                • Popular
                                • Users
                                • Groups
                                • Search
                                • Get Qt Extensions
                                • Unsolved