views:

855

answers:

6

I recently migrated my Qt project from Linux to Vista, and now I'm debugging signals blindly.

On Linux, if QObject::connect() fails in a debug build, I get a warning message on stderr. On Windows, there is no console output for GUI applications, only an OutputDebugString call.

I already installed DebugView, and it catches my own qDebug() output nicely, but still no warning on failed signals.

One possible solution would be to use QtCreator's autocomplete for signals, but I like Eclipse, and using both is a PITA. Any ideas on how to get signal/slot info at runtime?

Edit: I just realized connect() returns bool, which solves the immediate problem, ugly as it may be. However, this doesn't solve the cases where QMetaObject::connectSlotsByName() fails, and this one runs automatically with widgets.

A: 

If your using Visual Studio you can add a console to any QT application.
Go to the project properties, under Linker->Settings change the "SubSystem" to say "Console"

Now recompile your code and you'll the console will appear when you activate the application. If you want to get rid of it, just change the SubSystem again to "Windows"

I'm not sure if this is possibly with QtCreator.

Another option is to use native win32 calls like AttachConsole() to manually create the console and attach it to stdout and stderr. see here for more details on this.

shoosh
A: 

you can redirect stdout/stderr quite easily: make a class that derives from std::basic_streambuf and overloads xsputn() and overflow(), then use eg std::cerr.rdbuf( instanceOfYourRedirectClass ) to redirect all stderr ouptut to a callback funtion you supply.

Here's a simplified version of what I use; depending on your needs you might have to add extra logic to fiddle with the handling of end of line characters etc.

template< class Elem = char, class Tr = std::char_traits<Elem> >
class Redirector : public std::basic_streambuf<Elem, Tr>
{
  typedef void (*pfncb) ( const Elem*, std::streamsize );

public:
  Redirector( std::ostream& a_Stream, pfncb a_Cb ) :
    m_Stream( a_Stream ),
    m_pCbFunc( a_Cb ),
  {
      //redirect stream
    m_pBuf = m_Stream.rdbuf( this );
  };

  ~Redirector()
  {
      //restore stream
    m_Stream.rdbuf( m_pBuf );
  }

  std::streamsize xsputn( const Elem* _Ptr, std::streamsize _Count )
  {
    m_pCbFunc( _Ptr, _Count );
    return _Count;
  }

  typename Tr::int_type overflow( typename Tr::int_type v )
  {
    Elem ch = Tr::to_char_type( v );
    m_pCbFunc( &ch, 1 );
    return Tr::not_eof( v );
  }

 protected:
  std::basic_ostream<Elem, Tr>& m_Stream;
  std::streambuf*               m_pBuf;
  pfncb                         m_pCbFunc;
};

Usage:

  void outcallback( const char *ptr, std::streamsize count )
  {
    if( *ptr != gc_cEOL )  //ignore eof
      OutputDebugString( ptr );
  }

  Redirector<> redirect( std::cout, mycallback );
stijn
Does that redirect stdout with printf() too, or just std::cout? I'd suspect the latter, which makes it less helpful in this case.
Marcus Lindblom
+1  A: 

My approach is to rebind the Qt logging engine with qInstallMsgHandler and do my own logging both to file and console.

This way, I know that all of the error/warning messages are recorded and I can analyze them even after the program has stopped executing.

P.S: QtCreator intercepts those messages and displays them in the application output pane.

rpg
Thank you, this certainly helps, although I'm starting to believe the Qt DLL is just plain silent. I can already see qDebug() output, so in theory, it should have shown up in DebugView, too.
Jurily
+1  A: 

Call the static function QErrorMessage::qtHandler().

As per the documentation, this 'installs a message handler using qInstallMsgHandler() and creates a QErrorMessage that displays qDebug(), qWarning() and qFatal() messages'.

Alternatively, install a message handler with qInstallMsgHandler().

Another alternative (described in a qt-interest post) is something like this:

#ifdef _DEBUG
#define connect( connectStmt ) Q_ASSERT( connect( connectStmt ) ) 
#endif

...and for what it's worth, here are some signals and slots debugging suggestions I compiled: http://samdutton.wordpress.com/2008/10/03/debugging-signals-and-slots-in-qt/

Sam Dutton
+1  A: 

You can use the offical Qt IDE: QtCreator. It contains an output console where you will see any problem with signals. Signal error are output in debug AND release run.

Patrice Bernassola
A: 
Esben Mose Hansen