Frage

Ich wanderte vor kurzem mein Qt-Projekt von Linux auf Windows Vista, und jetzt Signale blind ich debuggen.

Unter Linux wenn QObject :: connect () nicht in einem Debug-Build, erhalte ich eine Warnmeldung auf stderr. Unter Windows gibt es keine Konsolenausgabe für GUI-Anwendungen, nur ein Output Anruf.

ich bereits installiert Debugview , und es fängt mein eigenes qDebug () -Ausgabe schön, aber immer noch keine Warnung über gescheiterte Signale.

Eine mögliche Lösung wäre QtCreator die die automatische Vervollständigung für Signale zu verwenden, aber Ich mag Eclipse und mit beiden ein PITA ist. Alle Ideen, wie Signal / Slot-Informationen zur Laufzeit bekommen?

Edit: Ich habe gerade connect realisiert () gibt Bool, die das unmittelbare Problem löst, hässlich, wie es sein kann. Allerdings bedeutet dies nicht, die Fälle lösen, wo QMetaObject :: connectSlotsByName () fehlschlägt, und dieser wird automatisch mit Widgets.

War es hilfreich?

Lösung

Rufen Sie die statische Funktion QErrorMessage :: qtHandler ().

Gemäß der Dokumentation dieses 'installiert einen Nachrichtenhandler mit qInstallMsgHandler () und erstellt eine QErrorMessage, die anzeigt, qDebug (), qWarning () und qFatal () Nachrichten'.

Alternativ installieren Sie eine Message-Handler mit qInstallMsgHandler ().

Eine weitere Alternative (in einem qt-Interesse Post beschrieben) ist so etwas wie folgt aus:

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

... und für das, was es wert ist, hier sind einige Signale und Slots Vorschläge Debug-I zusammengestellt: http://samdutton.wordpress.com/2008/10/03/debugging-signals-and-slots-in-qt/

Andere Tipps

Die Lösung, die ich für diese mag, ist auf

QT_FATAL_WARNINGS=1

in der Umgebung des Programms, wenn Sie debuggen. Das macht das Programm abstürzen, Ihnen eine schöne Backtrace zu geben, vor allem, wenn Sie den Code in einem Debugger ausführen. Wenn Sie nicht über den Absturz möchten, finden Sie die Antwort oben.

Mein Ansatz ist es, den Qt Logging Engine mit qInstallMsgHandler erneut zu binden und meine eigenen Protokollierung beides zu tun und Konsole Datei.

Auf diese Weise weiß ich, dass alle Fehler / Warnmeldungen aufgezeichnet werden und ich kann sie analysieren, selbst nachdem die Programmausführung gestoppt.

P. S: QtCreator dazwischen und diese Nachrichten und zeigt diese in der Anwendung Ausgabebereich

.

Wenn Ihr Visual Studio verwenden Sie eine Konsole zu einer QT-Anwendung hinzufügen können.
Gehen Sie zu den Projekteigenschaften unter Linker-> Einstellungen ändern, um das „SubSystem“ zu sagen „Console“

Jetzt Ihren Code neu kompilieren, und Sie werden die Konsole erscheint, wenn Sie die Anwendung zu aktivieren. Wenn Sie loswerden es erhalten wollen, nur die SubSystem ändern wieder auf „Windows“

Ich bin mir nicht sicher, ob dies möglicherweise mit QtCreator.

Eine andere Möglichkeit ist nativen Win32-Aufrufe verwenden wie AttachConsole() die Konsole manuell erstellen und an stdout und stderr befestigen. finden Sie unter hier , um weitere Informationen zu diesem Thema.

Die meiste Zeit will ich nur einige Aufmerksamkeit von Zeit zu Zeit: Legen Sie einfach einen Haltepunkt auf Zeile „int dummyPutBreakpointHere = 23;“

in main.C:

static QtMessageHandler defaultMessageHandler;
void myRazorsharpMessageHandler(QtMsgType type, const QMessageLogContext& context, const QString& msg) 
{
    if ( type > QtDebugMsg ) {
        int dummyPutBreakpointHere= 23;
    }
    defaultMessageHandler(type, context, msg);
}
...
later in main(): defaultMessageHandler= qInstallMessageHandler(0);

Sie können die offiziellen Qt-IDE verwenden: QtCreator . Es enthält eine Ausgabekonsole, wo Sie ein Problem mit Signalen sehen. Signalfehler ausgegeben werden im Debug-und Release-Lauf.

Sie können stdout / stderr ganz einfach umleiten: eine Klasse machen, die von std :: basic_streambuf leitet und Überlastungen xsputn () und Überlauf (), dann verwenden Sie zB std :: cerr.rdbuf (instanceOfYourRedirectClass) alle stderr ouptut umleiten zu eine Callback-Funktion Sie liefern.

Hier ist eine vereinfachte Version von dem, was ich verwende; Je nach Bedarf können Sie zusätzliche Logik zur Geige mit der Handhabung von Zeilenende Zeichen etc.

hinzufügen müssen
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;
};

Verbrauch:

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

  Redirector<> redirect( std::cout, mycallback );
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top