2009-09-28 16 views
10

私は最近、LinuxからVistaへQtプロジェクトを移行しました。今は盲目的に信号をデバッグしています。Qt GUIアプリケーション:QObject :: connect()が失敗した場合の警告?

Linuxでは、QObject :: connect()がデバッグビルドで失敗すると、stderrに警告メッセージが表示されます。 Windowsでは、GUIアプリケーションのコンソール出力はなく、OutputDebugString呼び出しのみです。

私は既にDebugViewをインストールしていて、自分自身のqDebug()出力をうまくキャッチしますが、失敗した信号については警告は表示されません。

QtCreatorのオートコンプリートをシグナルに使用することができますが、私はEclipseが好きで、どちらもPITAです。実行時に信号/スロット情報を取得する方法に関するアイデアはありますか?

編集:私はconnect()が直近の問題を解決するboolを返すことを認識しましたが、醜いかもしれません。しかし、これはQMetaObject::connectSlotsByName()が失敗した場合を解決するものではなく、ウィジェットで自動的に実行されます。

答えて

10

静的関数QErrorMessage :: qtHandler()を呼び出します。

ドキュメントごとに、これはqInstallMsgHandler()を使用してメッセージハンドラをインストールし、qDebug()、qWarning()およびqFatal()メッセージを表示するQErrorMessageを作成します。

また、qInstallMsgHandler()を使用してメッセージハンドラをインストールしてください。

(QT-金利記事で説明した)別の方法としては、このようなものです:

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

...そして、それは価値がある何のために、ここで私はコンパイルの提案デバッグいくつかのシグナルとスロットです:http://samdutton.wordpress.com/2008/10/03/debugging-signals-and-slots-in-qt/

は、
+1

これは本当に便利です! – Pepe

1

Visual Studioを使用している場合は、任意のQTアプリケーションにコンソールを追加できます。リンカー - > [設定]の下に移動し、プロジェクトのプロパティに
は、

今すぐあなたのコードを再コンパイルして、アプリケーションを起動するときにコンソールが表示されますよ「コンソール」を言うために、「サブシステム」に変更します。それを取り除きたいのであれば、SubSystemを再び "Windows"に変更してください。

これはおそらくQtCreatorであるかわかりません。

別のオプションは、AttachConsole()などのネイティブwin32コールを使用して、コンソールを手動で作成してstdoutとstderrに接続することです。詳細はhereを参照してください。

0

stdout/stderrを簡単にリダイレクトすることができます。std :: basic_streambufから派生し、xsputn()とoverflow()をオーバーロードし、次にstd :: cerr.rdbuf(instanceOfYourRedirectClass)を使用してすべてのstderr ouptutあなたが提供するコールバック関数に渡します。

ここでは、私が使っているものを簡略化したものです。

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

    Redirector<> redirect(std::cout, mycallback); 
+0

これはprintf()でstdoutをリダイレクトするのか、std :: coutだけでリダイレクトするのでしょうか?私は後者を疑うだろうが、この場合はあまり役に立たない。 – Macke

2

私のアプローチqInstallMsgHandlerとQtのロギングエンジンを再バインドすることです:ニーズに応じて、あなたは

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; 
}; 

使用法など行末文字の取り扱いをいじるために余分なロジックを追加する必要がある場合がありますファイルとコンソールの両方に自分のログを記録します。

このようにして、すべてのエラー/警告メッセージが記録され、プログラムの実行が停止した後でも解析できることがわかりました。

P.S:QtCreatorはこれらのメッセージを傍受し、アプリケーションの出力ウィンドウに表示します。

+0

ありがとう、これは確かに役に立ちますが、私はQt DLLが単なる無音だと考え始めました。私はすでにqDebug()の出力を見ることができるので、理論上はDebugViewにも表示されているはずです。 –

1

公式のQt IDE:QtCreatorを使用することができます。これには出力コンソールが含まれており、信号に問題があることがわかります。信号エラーは、デバッグアンドリリース実行時に出力されます。

4

私はこのために好きな解決策は、あなたがデバッグするときに、プログラムの環境で

QT_FATAL_WARNINGS=1 

を設定することです。そうすれば、プログラムがクラッシュし、特にデバッガでコードを実行すると、良いバックトレースが得られます。クラッシュしたくない場合は、上記の答えをご覧ください。

+0

MinGWで、悲しいことにバックトレースがありません:「アプリケーションに異常な方法で...あります」(おそらくMSVCでうまくいく)。 – mlvljr

+0

CONNECTを再定義すると解決されなかったため、解決策として(VS 2012のコールスタックが表示されています)、特にバインディングの問題が別のDLLにある場合 – Samuel

0

ほとんどの場合、今私はちょうど今注目したいです: "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); 
関連する問題