我最近迁移我的Qt项目从Linux到Vista的,现在我盲目地调试信号。
在Linux上,如果的QObject ::连接()在调试构建失败,我得到一个标准错误警告信息。 在Windows上,没有控制台输出GUI应用程序,只是一个OutputDebugString的调用。
我已经安装的DebugView ,它很好地抓住我自己qDebug()输出,但仍然未能信号没有任何警告。
一个可行的办法是使用QtCreator的自动完成的信号,但我喜欢的Eclipse,并同时使用是一个PITA。 关于如何在运行时获得的信号/槽信息任何想法?
编辑:我只是意识到连接()返回布尔值,解决了眼前的问题的,丑陋的,因为它可能。 然而,这并没有解决其中的情况下QMetaObject :: connectSlotsByName()失败,而这一次与小工具会自动运行。
调用静态函数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/
我喜欢这个解决方案是设置
QT_FATAL_WARNINGS=1
在程序的环境,当你调试。 这使得程序崩溃,给你一个很好的回溯,特别是如果你在运行调试器的代码。 如果你不想崩溃,看到上面的答案。
我的做法是重新绑定与Qt的日志引擎qInstallMsgHandler
,做自己的记录既文件和控制台。
这样一来,我知道所有的错误/警告信息被记录下来,我可以分析该程序已停止执行它们甚至后。
PS:QtCreator拦截那些消息并将它们显示在应用输出窗格。
如果您使用Visual Studio您可以将控制台添加到任何Qt应用程序。
转到项目属性,链接器下>设置改变“子系统”说“控制台”
现在,重新编译代码,你会当你启动应用程序的控制台将出现。 如果你想摆脱它,只是再次更改子系统为“Windows”
我不知道这是否可能与QtCreator。
另一种选择是使用原生Win32调用像AttachConsole()
手动创建控制台并将其连接到输出和错误。 看到这里更多这方面的细节。
大多数时候,我只是想一些关注,现在再:只要把一个断点上线“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);
您可以使用正式的Qt IDE: QtCreator 。 它包含一个输出的控制台,你会看到任何问题的信号。 信号错误是在调试和发布运行输出。
你可以/标准错误很容易将stdout:从中赚取的std :: basic_streambuf派生和过载xsputn()和溢出()类,然后使用如的std :: cerr.rdbuf(instanceOfYourRedirectClass)所有标准错误ouptut重定向到一个回调函数你提供。
下面是我用一个简化版本; 根据你的需要,你可能需要添加额外的逻辑与行的字符等最终的处理捣鼓
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;
};
用法:
void outcallback( const char *ptr, std::streamsize count )
{
if( *ptr != gc_cEOL ) //ignore eof
OutputDebugString( ptr );
}
Redirector<> redirect( std::cout, mycallback );