環境
系統:win7 64位旗艦版
軟件:VS2013、QT5.5.1-32位、Qt5 Visual Studio Add-in1.2.4
概述
使用QT Visual Studio插件打開pro項目后,修改其中一個cpp文件進行編譯時,會重新生成大量moc文件,然后編譯moc,非常浪費時間。
原因
分析發現直接通過VS創建qt項目時,不會重新編譯,最后才發現是轉換pro文件時,添加一些無用的命令生成的。
1)查看.h文件自定義生成工具命令行(在.h文件上右鍵->屬性->自定義生成工具->常規->命令行)

注意不是所有的.h文件命令行中都有內容,前提是class中有Q_OBJECT宏。
2)刪除從setlocal開始到endlocal之間的字符后然后保存,修改其他文件,如果文件之間沒有關聯,則不會重新生成/編譯moc文件。
解決方案
由於一個項目中的.h文件比較多,我們手動一個一個改不現實,工作量比較大,這里寫一個程序用於去除工程中的無效命令。
主要的流程是:
1)讀取vcxproj文件內容。
2)循環查找setlocal開始endlocal結束的字符,找到后,刪除這些字符。
3)循環結束后,備份vcxproj文件為vcxproj.backup。
4)將內容寫入vcxproj文件。
文件讀取、備份、寫入不再詳細描述,這里主要說明查找/刪除的過程。
1)使用STL正則表達式查找,並替換為空字符串(相當於刪除),但是正則替換不能知道替換的個數,所以這里仿照STL正則替換函數進行擴展,增加了一個參數,返回替換個數的結果。
namespace ext { template<class _RxTraits, class _Elem, class _Traits2, class _Alloc2> std::basic_string<_Elem> regex_replace( const _Elem *_Pstr, const std::basic_regex<_Elem, _RxTraits>& _Re, const std::basic_string<_Elem, _Traits2, _Alloc2>& _Fmt, int* _Count = NULL, std::regex_constants::match_flag_type _Flgs = std::regex_constants::match_default) { // search and replace, string result, NTBS target, string format std::basic_string<_Elem> _Res; const std::basic_string<_Elem> _Str(_Pstr); std::basic_string<_Elem>::const_iterator _Pos = _Str.begin(); std::basic_string<_Elem>::const_iterator _Last = _Str.end(); auto _Result = std::back_inserter(_Res); std::match_results<std::basic_string<_Elem>::const_iterator> _Matches; std::regex_constants::match_flag_type _Flags = _Flgs; std::regex_constants::match_flag_type _Not_null = (std::regex_constants::match_flag_type)0; if (_Count) *_Count = 0; while (std::regex_search(_Pos, _Last, _Matches, _Re, _Flags | _Not_null)) { // replace at each match if (_Count) (*_Count)++; if (!(_Flgs & std::regex_constants::format_no_copy)) _Result = _Copy_impl(_Matches.prefix().first, _Matches.prefix().second, _Result); _Result = _Matches._Format(_Result, _Unchecked(_Fmt.begin()), _Unchecked(_Fmt.end()), _Flags); _Pos = _Matches[0].second; if (_Pos == _Last || _Flgs & std::regex_constants::format_first_only) break; if (_Matches[0].first == _Matches[0].second) _Not_null = std::regex_constants::_Match_not_null; else { // non-null match, recognize earlier text _Not_null = (std::regex_constants::match_flag_type)0; _Flags |= std::regex_constants::match_prev_avail; } } // 沒有可替換的,則將余下的字符串復制。 _Copy_impl(_Pos, _Last, _Result); return _Res; } }
2)使用擴展函數進行正則替換。
std::regex reg("setlocal(.|\r\n|\n)*?endlocal"); std::string rep = ""; int count = 0; std::string ret = ext::regex_replace(content.c_str(), reg, rep, &count);
總結:
如果對正則感興趣可以查看我的另一篇文章:http://www.cnblogs.com/dongc/p/5225114.html。
最后完成的Demo:qt_project.zip
