Results 1 to 10 of 10

Thread: Redirect printf to QTextEdit?

  1. #1
    Join Date
    Aug 2006
    Posts
    20
    Qt products
    Qt4
    Platforms
    Windows

    Default Redirect printf to QTextEdit?

    Hi!
    I first posted this question in the qtforum.org and was asked to also post it here. Link to the thread.

    I have qtgui that uses a lot of classes that dont use qt. In those classes there are a lot of printf. I need to redirect them form the console to a QTextEdit or some sort of component in my gui for example one of these:
    . I cant change the printfs since its not my code and there could be a lot of them hidden.
    I have tried the class in this thread
    and it works great for std::cout but not for printf and there is also seems to be some issues when using threaded classes.

    I guess I have to pipe the stdout in some way but I haven't a clue on how to do it.
    Would really appriciate any help I could get.

    There is some code that might help in understanding what I want to do in the original post.

    The q_debugstream.h is here:

    [Edit] Forgot to say, it's windows

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Redirect printf to QTextEdit?

    You could try:

    Qt Code:
    1. f.open(STDOUT, QFile::ReadOnly);
    To copy to clipboard, switch view to plain text mode 
    and then read from it. It will probably not work, because probably you can't read from STDOUT, but it's the only way I can think of that would work on Windows without using an external process (using QProcess). If the "printf-enabled" application was a separate process which you could call from your application, there wouldn't be a problem.

  3. #3
    Join Date
    Jan 2006
    Location
    Munich, Germany
    Posts
    4,714
    Thanks
    21
    Thanked 418 Times in 411 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: Redirect printf to QTextEdit?

    I don't see how the Qt qrapper classes in the threads you quoten could help you even if they would redirect printf().
    You said you can't/don't want to change the code where the printf()'s are, since you are not sure you can find them (which is not true, you can apply a search on all the files in the project).
    Never mind for what reason, you don't want to change the code - but applying the wrapper classes will demand that you insert code that uses the wrappers.

    A posibility to do what you want would be to use QProcess and to read the printf() output from the console in to a QTextEdit or any other place.
    This way you add only one code portion that deals with all the printf() output.
    EDIT: beat by wysota

  4. #4
    Join Date
    Aug 2006
    Posts
    20
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Redirect printf to QTextEdit?

    Quote Originally Posted by high_flyer View Post
    I don't see how the Qt qrapper classes in the threads you quoten could help you even if they would redirect printf().
    Well they won't, the first one was just an example of an output and the other link was able to redirect std::cout's to an QTextEdit but not printf.
    Quote Originally Posted by high_flyer View Post
    You said you can't/don't want to change the code where the printf()'s are, since you are not sure you can find them (which is not true, you can apply a search on all the files in the project).
    Yes I can find them but I don't want to change them because then I have to do it everytime the code is updated. But I can't find the ones or change the ones that might be in the libs, and I know there are a few.
    Quote Originally Posted by high_flyer View Post
    A posibility to do what you want would be to use QProcess and to read the printf() output from the console in to a QTextEdit or any other place.
    Hmm, that might actually be a good idea. I will take a look at that.

    This is what I have done so far. It doesent really work yet but I think this is one way to do it. I created a pipe and made a dublicate of stdout. Then I just have to read from it and output it in my TE.
    Qt Code:
    1. #include <QApplication>
    2.  
    3. #include <QTimer>
    4. //#include "q_debugstream.h"
    5. #include "stdoutredirector.h"
    6. #include "testwidget.h"
    7.  
    8. int main(int argc, char **argv)
    9. {
    10. printf("This should be display!\n");
    11.  
    12.  
    13. StdOutRedirector *redir = new StdOutRedirector;
    14.  
    15. //printf("This should go to fdguistd\n");
    16.  
    17.  
    18. QApplication app(argc, argv);
    19. TestWidget tw;
    20. tw.show();
    21. redir->setOutputTF(tw.qte);
    22. printf("Testing redirection\n");
    23. redir->readOutsToTF();
    24.  
    25. // Make a QTimer that update the read every 40 ms
    26. QTimer *redirTimer = new QTimer;
    27. //QObject::connect(redirTimer, SIGNAL(timeout()), redir, SLOT(readOutsToTF()));
    28. //redirTimer->start(40);
    29.  
    30. //Q_DebugStream cout(std::cout, tw.qte);
    31. //Q_DebugStream cerr(std::cerr, tw.qte);
    32.  
    33. std::cout << "Printing something else" << std::endl;
    34. redir->readOutsToTF();
    35. return app.exec();
    36. }
    To copy to clipboard, switch view to plain text mode 
    Qt Code:
    1. #ifndef STDOUTREDIRECTOR_H
    2. #define STDOUTREDIRECTOR_H
    3. #include <QString>
    4. #include <iostream>
    5. #include <stdio.h>
    6. #include <fcntl.h>
    7. #include <io.h>
    8. #include <QTextEdit>
    9.  
    10. class StdOutRedirector : public QObject
    11. {
    12. Q_OBJECT
    13. public:
    14. StdOutRedirector()
    15. {
    16. // Redirect
    17. if(_pipe(fdguistd, 512, _O_BINARY) == -1)
    18. printf("failed!");
    19. // Duplicate stdout file descriptor (next line will close original)
    20. fdStdOut = _dup(_fileno(stdout));
    21. // Duplicate write end of pipe to stdout file descriptor
    22. if(_dup2(fdguistd[1], _fileno(stdout)) != 0)
    23. printf("failed!");
    24. // Close original
    25. close(1);
    26. // Duplicate write end of original
    27. dup2(fdguistd[1], 1);
    28.  
    29. }
    30. void setOutputTF(QTextEdit *_output)
    31. {
    32. output = _output;
    33. }
    34. //public slots:
    35. void readOutsToTF()
    36. {
    37. int nout;
    38. char *buffer = new char [512];
    39. //char buffer[512];
    40. printf(" ");
    41. fflush(stdout);
    42.  
    43. nout = _read(fdguistd[0], buffer, 512);
    44.  
    45. if(nout <= 0)
    46. return;
    47. if(nout) {
    48. QString str;
    49. //output->append(str.setNum(nout));
    50. output->append(QString(buffer));
    51. }
    52. delete buffer;
    53. }
    54. private:
    55. QTextEdit *output;
    56. int fdStdOut;
    57. int fdguistd[2];
    58.  
    59. };
    60.  
    61.  
    62. #endif
    To copy to clipboard, switch view to plain text mode 

    One problem is that when there is nothing in the fdguistd buffer it stops there. Another is that it doesent output the text in TE until it reaches the last line in the main method.
    Last edited by Randulf; 9th October 2006 at 12:09.

  5. #5
    Join Date
    Sep 2006
    Posts
    5
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Redirect printf to QTextEdit?

    I seem to have a similar request for my project.
    In my huge C code base we printed:
    Informational messages,
    Warning messages,
    Error messages.

    All of the obviously doen with printf().
    So we created our own version that sended out signals
    with the corresponding ascii line as an argument.
    I was lucky that we had our own routines for printing
    but I guess some nifty #define can do the trick/ or a big grep.

    Anyway the signal solution is realy neat. It's thread safe and does
    not add a lot of overhead. I tested it with several million of messages
    and there was not a big impact on the performance.

    You do need to take care of the C -> C++ wrappers though.
    Otto Meijer
    email: otto.meijer@synopsys.com

  6. #6
    Join Date
    Apr 2006
    Location
    San Francisco, CA
    Posts
    186
    Thanks
    55
    Thanked 12 Times in 11 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Windows

    Default Re: Redirect printf to QTextEdit?

    Quote Originally Posted by Randulf View Post
    One problem is that when there is nothing in the fdguistd buffer it stops there.
    Perhaps there is a non-blocking version of _read() that you can call?

    Quote Originally Posted by Randulf View Post
    Another is that it doesent output the text in TE until it reaches the last line in the main method.
    Perhaps need a call to fflush(stdout) ? Or maybe some way to send EOF byte?
    Software Engineer



  7. #7
    Join Date
    Aug 2006
    Posts
    20
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Redirect printf to QTextEdit?

    Quote Originally Posted by cwomeijer View Post
    So we created our own version that sended out signals
    with the corresponding ascii line as an argument.
    But then you had to implement a signal in every class?
    Or how did you do it?
    Quote Originally Posted by gfunk View Post
    Perhaps there is a non-blocking version of _read() that you can call?
    Exactly, been looking for that or the possibility to set fcntl O_NONBLOCK but I cant find how to that in windows. For now problem was solved by adding a \n before I do fflush.

    Now I think it's working with some cheating.

    Qt Code:
    1. #ifndef STDOUTREDIRECTOR_H
    2. #define STDOUTREDIRECTOR_H
    3. #include <QString>
    4. #include <iostream>
    5. #include <stdio.h>
    6. #include <fcntl.h>
    7. #include <io.h>
    8. #include <QTextEdit>
    9.  
    10. class StdOutRedirector : public QObject
    11. {
    12. Q_OBJECT
    13. public:
    14. StdOutRedirector()
    15. {
    16. // Redirect
    17. if(_pipe(fdguistd, 4096, _O_BINARY) == -1)
    18. printf("failed!");
    19. //int tr = fcntl(fdguistd, O_NONBLOCK);
    20. // Duplicate stdout file descriptor (next line will close original)
    21. fdStdOut = _dup(_fileno(stdout));
    22. // Duplicate write end of pipe to stdout file descriptor
    23. if(_dup2(fdguistd[1], _fileno(stdout)) != 0)
    24. printf("failed!");
    25. // Close original
    26. close(1);
    27. // Duplicate write end of original
    28. dup2(fdguistd[1], 1);
    29.  
    30. }
    31. void setOutputTF(QTextEdit *_output)
    32. {
    33. output = _output;
    34. }
    35. public slots:
    36. void readOutsToTF()
    37. {
    38. int n_out;
    39. char *buffer = new char [4096];
    40. QString str;
    41. //char buffer[512];
    42. printf("\n");
    43. fflush(stdout);
    44.  
    45. n_out = _read(fdguistd[0], buffer, 4096);
    46.  
    47. if(n_out <= 0)
    48. return;
    49. if(n_out > 1) {
    50. str.append(QString(buffer));
    51. int con = str.lastIndexOf('\n');
    52. int remv = str.at(con-1) == '/n' ? 1 : 0;
    53. if(con) {
    54. str = str.remove(con-remv, str.length());
    55. output->append(str);
    56. }
    57. }
    58.  
    59. }
    60. private:
    61. QTextEdit *output;
    62. int fdStdOut;
    63. int fdguistd[2];
    64. };
    65. #endif
    To copy to clipboard, switch view to plain text mode 

  8. #8
    Join Date
    Sep 2006
    Posts
    5
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Redirect printf to QTextEdit?

    Because we had a huge code base (10M lines C code)
    we wrote a wrapper around all of this as a single class.
    Now this class obvious has the information, warning and error singals
    defined in them.

    From there it can be used throughout the code as any other class would be.
    We needed to write little wrapper routines such that the emits could be
    called inside our C code but that was not to difficult.

    Again it is not the cleanest solution, however it did the trick with minimal
    modification to our original code base.

    If wanted I can post a little snippet of our code.
    (I don't have acces to the code right now)
    Otto Meijer
    email: otto.meijer@synopsys.com

  9. #9
    Join Date
    Aug 2006
    Posts
    20
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Redirect printf to QTextEdit?

    Quote Originally Posted by cwomeijer View Post
    Because we had a huge code base (10M lines C code)
    we wrote a wrapper around all of this as a single class.
    Now this class obvious has the information, warning and error singals
    defined in them.

    From there it can be used throughout the code as any other class would be.
    We needed to write little wrapper routines such that the emits could be
    called inside our C code but that was not to difficult.

    Again it is not the cleanest solution, however it did the trick with minimal
    modification to our original code base.

    If wanted I can post a little snippet of our code.
    (I don't have acces to the code right now)
    That would be really nice, it's always intresting to view other solutions.
    The above code actually works (to my surprise), tried it today in my application. And it works for both std::cout and printf's but not qDebug. It still needs some work though.

  10. #10
    Join Date
    Sep 2006
    Posts
    5
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Redirect printf to QTextEdit?

    Here is the code we use inside the class:

    void CatsCore::makeSignal(int type, char *str)
    {
    QString msg(str);

    switch (type) {
    default:
    case 0:
    emit information(msg);
    break;
    case 1:
    emit warning(msg);
    break;
    case 2:
    emit error(msg);
    break;
    case 3:
    emit progress(msg);
    break;
    }
    }
    }

    extern "C" void emitInfo(char *str)
    {
    Cats::globalCats->makeSignal(0,str);
    }

    extern "C" void emitWarning(char *str)
    {
    Cats::globalCats->makeSignal(1,str);
    }

    extern "C" void emitError(char *str)
    {
    Cats::globalCats->makeSignal(2,str);
    }

    extern "C" void emitProgress(char *str)
    {
    Cats::globalCats->makeSignal(3,str);
    }


    Because there can only be one Cats class we use the Cats::globalCats
    to get a hold of the instance.
    Otto Meijer
    email: otto.meijer@synopsys.com

Similar Threads

  1. a question about visualizing cursor in read-only QTextEdit
    By kennyxing in forum Qt Programming
    Replies: 3
    Last Post: 17th September 2006, 19:52
  2. QTextEdit API questions (plain text)
    By Gaspar in forum Qt Programming
    Replies: 4
    Last Post: 16th May 2006, 06:03
  3. [QT 4] QTextEdit performance
    By fellobo in forum Qt Programming
    Replies: 8
    Last Post: 6th March 2006, 19:27
  4. Painting to QTextEdit
    By gesslar in forum Qt Programming
    Replies: 8
    Last Post: 18th February 2006, 18:40
  5. Obtaining clean (x)html from QTextEdit
    By ccf_h in forum Qt Programming
    Replies: 1
    Last Post: 5th February 2006, 14:47

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.