Qt编程点滴

类定义后面要加";" 函数的实现部分,如果定义部分有void,则实现部分不能少; 检查include文件有无少; error: request for member `show' in `((MainWindow*)this)->MainWindow::rightform', which is of non-class type `RightForm*'| "->"与"."问题 函数"()"千万不能少; connect中的SLOT里的自定义过程的申明一定要写在private slots:(或public slots:)下 QTableWidgetItem *newItemName = new QTableWidgetItem(tr("姓名")); newItemName->setFlags(newItemName->flags() & (~Qt::ItemIsEditable));//网格设置为只读 tblWidgetMingPian->setItem(0, 0, newItemName); newItemName = new QTableWidgetItem(tr("陈林 & (~Qt::ItemIsEditable)); tblWidgetMingPian->setItem(0, 1, newItemName); tblWidgetMingPian->verticalHeader()->hide(); tblWidgetMingPian->horizontalHeader()->hide(); tblWidgetMingPian->setRowHeight(0,25); tblWidgetMingPian->setRowHeight(1,25); tblWidgetMingPian->setRowCount(2);connsql.h tblWidgetMingPian->setColumnWidth(0,60); tblWidgetMingPian->setColumnWidth(1,100); if 里面的语句要加括号 if (条件) 枚举类型的定义: typedef enum{ nil, ready, fired, exceptional }Status; QString text = tr("%1 %2").arg(i + 1).arg(files[i]); Error:ISO C++ forbids declaration of `NavItem' with no type 如果出现以上的错误,其中NavItem是自定义类,则需检查有没Include 进此类的定义头文件, 并检查头文件的#ifndef中的名称跟其他类有没重复(在复制其它类生成新类时经常会出现这样的错误) ===================================================================================== /mingw/lib/libmingw32.a(main.o):main.c:(.text+0x104)||undefined reference to `WinMain@16'| 往 pro文件按顺序加入下面三行: -lmingw32 / -lSDLmain / -lSDL / sdl库中文件(sdl.h)里将 #include "SDLMain.h" 注释掉,否则qDebug(),printf全部无法显示 有可能使用 #pragma message()造成,方法:不使用#pragma message() 另:请检查 pro文件里有没INCLUDE入 main.cpp ======================================================================== cannot open output file debug/umpcphonegui.exe: Permission denied 产生此问题是由于文件umpcphonegui.exe受到保护,写不进去,打开任务管理器结束掉此进程就好了 ======================================================== pages.h|16|error: expected class-name before '{' token| ||=== Build finished: 1 errors, 0 warnings ===| 处理方法:没有include进所需的类 链接时提示""undefind reference to 'vtable for xxx'错误的处理方法: 重新makefile试下或 工程文件(.pro)中的HEADERS中没有加入定义该类的.h文件;另一原因,虚函数(或调用的虚函数)定义后没有加"=0"; int x,y; setupUi(this); this->move(10,60); this->resize(338,568); x = this->x() + this->frameGeometry().width(); y = this->y() + 20 ; //showMaximized(); rightform = new RightForm; rightform->move(x,y); ERROR:undefined reference to `RightGpsForm::RightGpsForm(QWidget*) 工程文件(*.pro)文件中的Source没有加入 RightGpsForm类实现的.cpp文件 头部定义有误,需检查头部名称跟文件名是否一样; 尝试重编译 error: ISO C++ forbids declaration of `GPSMainWindow' with no type| 类的定义GPSMainWindow(gpsmainwindow.h)中的 #ifndef MAINWINDOW_H_INCLUDED #define MAINWINDOW_H_INCLUDED 头部定义有误,需检查头部名称跟文件名是否一样; #include 时,提示下面的错误: QList: No such file or directory 解决方法: Project-build options-选择整个工程(左侧第一项)--切到右边的页"Search directories" 增加"$(#qt4.include)/QtGui/QtCore" QT中的目录用"/"表示 应用程序目录:QCoreApplication::applicationDirPath().append(tr("/world.png")); ========================= QSS: 设置TabWidget中的Tab页高度 QTabBar::tab { height: 14ex; width: 14ex; } ====================== TRACE_SUBSYSF(MYRUNLEVEL,MYMODULENAME,QString(QObject::tr(" 测试数据"))<<10); TRACE_LEVEL=5 TRACE_SUBSYS=MAIN /d/study/umpcapp/umpcapp-dev-1.0.0/gpsapp/deb ug/gpsapp.exe TRACE_SUBSYSF(5,"GUIAPP",QString(QObject::tr("构造函数创建完毕"))<<10); TRACE_SUBSYSF(5,"GUIAPP",tr("构造函数创建完毕")<<10); int ret = QMessageBox::question (this, tr("提示"), tr("确定要删除文件吗?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::No); 引用Dll文件(动态链接"qextserialport.dll")时,需在pro里加下面的语句, -l+dll文件名 LIBS += -lqextserialport // // listWidget->addItem("a"); // listWidget->addItem("b"); // QVariant var; // var.setValue (new int(789098)); // // listWidget->item(0)->setData(Qt::UserRole,var); // // int* ptr = listWidget->item(0)->data(Qt::UserRole).value < int* >(); // qDebug()<< "RecentNoteListForm::RecentNoteListForm:" << *ptr << endl; // delete ptr; // delete &listWidget->item(0)->data(Qt::UserRole); 删ITEM方法: 把把ITEM的数据挂到指针上,先删ITEM,然后再删除指针 如果发生 no such file or directory not find(报QT核心文件错) 有可能是project --properties--projects settings中的"This is a custom MakeFile"没有勾选; 检查.pro文件是 INCLUDEPATH += DEPENDPATH+= 有没加入文件所在的目录 检查.pro文件是否引入两个版本不同的相同文件名的文件; Qt += GUI ============================================ 枚举类型做为信号的参数,则需对枚举类型进行注册 在include中 //定义Enum typedef enum{ ProgressType, StartType, SuccessType, StopType }SyncMsgType; //定义结构 typedef struct //实际使用中可以多增加些结构成员 { SyncMsgType msgtype; }SyncMsg; Q_DECLARE_METATYPE(SyncMsg) 在应用程序.CPP中 //连接之前再注册 qRegisterMetaType("SyncMsg"); connect(gpssyncthread, SIGNAL(syncMsgNotify(SyncMsg)), this, SLOT(syncMsgEvent(SyncMsg))); ======================================== QList listItemDatas; for (QList::iterator it=listItemDatas.begin(); it!=listItemDatas.end() ; ++it) { (*it)->colName; } ================== error: multiple types in one declaration 自定义的类 {}后面没有";" 还有一种可能是pro文件中引用了两次单元文件; 重编译方法 ===================================== expected unqualified-id before "int" 前一句的";"误写为"," ====================================== 在Bulid工程时,qmake *.pro死循环,原因:pro文件里同一文件包含两次; =========================== char *const p ; p所指向的值不能变; char cont *p; P所指向的地址不能变; =========================== error: `nameLineEdt' was not declared in this scope 函数域没有写; (函数域::函数名()) ifdef/define重覆 ============================== int main(int argc, char *argv[]) { Q_INIT_RESOURCE(qtdam); QApplication app(argc, argv); QSplashScreen *splash = new QSplashScreen; QString path=app.applicationDirPath(); IDIOMA *lang = new IDIOMA(); lang->setfile_idioma(path+"/languages.lng"); if (lang->idioma_seleccionado=="Español") splash->setPixmap(QPixmap(":/images/splash_espagnol.png")); else splash->setPixmap(QPixmap(":/images/splash.png")); splash->show(); Qt::Alignment topRight = Qt::AlignRight | Qt::AlignTop; splash->showMessage(lang->leer_idioma("1"),topRight, Qt::white); MainWindow mainWin; mainWin.show(); splash->finish(&mainWin); delete splash; return app.exec(); } =============================== 函数如果有返回值必须写,否则有造成一些不确定的错误 如: QString a() { } QString str; str = "abc"; str.append(a()); QMessageBox::warning(this, tr("呼叫"),str,QMessageBox::Ok); 上面的情况,对话框可以出来,但点击对话框中的"确定"后,程序会死在那; ===================================================== 进行信号连接时,要确保连接参数中的对象已经创建过,否则会报保护错; 图片加载不了,有可能是QT库中的插件库没有拷贝; 加载路径指令: QCoreApplication::addLibraryPath(QObject::tr("%1%2plugins").arg(QCoreApplication::applicationDirPath()).arg("/")); qDebug() << "插件加载的路径是(QCoreApplication::libraryPaths):" << QCoreApplication::libraryPaths()<(childAt(event->pos())); if (!child) return; QPixmap pixmap = *child->pixmap(); QByteArray itemData; QDataStream dataStream(&itemData, QIODevice::WriteOnly); dataStream << pixmap << QPoint(event->pos() - child->pos()); ================================================= 取得应用程序所在路径,注:结果后面未加"/" QCoreApplication::applicationDirPath() =================================================== *.hpp文件,如果改动,Bulid后对改动后代码不起作用,必须ReBulid才可以; ================================================================= 静态成员变更量 aa.h class AA { static char p[13]; }; aa.cpp char AA::p[13]; 如果没在cpp中增加"char AA::p[13];",则编译时会提示"undefined reference to...."的错误 ==================================================================== b.h 接口中引用a.h接口 使用时必须加上 include "a.h" include "b.h" 否则编译时会出现"如果没在cpp中增加"char AA::p[13];",则编译时会提示" ========================================================================= 单例模式singleton单元要最先初始化(#include放到最前面) 错误: 'Singleton' is not a template 解决方法: #include "singleton.hpp" using namespace Pattern; =========================================================== QWidget 类以模式窗体显示: dailPage = new DailForm(0,tel); dailPage->setWindowModality(Qt::ApplicationModal); dailPage->show(); ================================================================ 事件过滤写法: 其实可以通过重载QWidget::keyPressEvent()获得本类(假设是窗体)中的几乎所有键盘事件,但焦点在文本框上,就不属于窗体类啦,所以必须采用在窗体类中添加Event Filters: CustomerInfoDialog::CustomerInfoDialog(QWidget *parent) : QDialog(parent) { ... firstNameEdit->installEventFilter(this); lastNameEdit->installEventFilter(this); cityEdit->installEventFilter(this); phoneNumberEdit->installEventFilter(this); } 然后在eventFilter中处理相关键盘事件,通过target判断是否是文本框发生的键盘事件 bool CustomerInfoDialog::eventFilter(QObject *target, QEvent *event) { if (target == firstNameEdit || target == lastNameEdit || target == cityEdit || target == phoneNumberEdit) { if (event->type() == QEvent::KeyPress) { QKeyEvent *keyEvent = static_cast(event); if (keyEvent->key() == Qt::Key_Space) { focusNextChild(); return true; } } } return QDialog::eventFilter(target, event); } ======================================================================== 去掉窗体标题栏: setWindowFlags(Qt::FramelessWindowHint); ============================================================== ld.exe cannot find -lSDL 处理:环境变量path加入"D:/QtDevelop/umpcapp/public/SDL- 1.2.13/bin" =========================== 环境变量path的设置: D:/QtDevelop/umpcapp/public/STLport-5.1.3/bin; D:/MinGW/bin; D:/Qt/bin; D:/QtDevelop/umpcapp/public/SDL-1.2.13/bin; D:/QtDevelop/umpcapp/public/SDL_mixer-1.2.8/bin 注:STLport-5.1.3一定要放在MinGW前面,不然会出现 "QImage: out of memory, returning null image"的错误; ================================================== 如果要用到STLport库,那么在配置.pro文件时,一定要记住把stlport放在其它库的前面, 下面的写法是正确的: INCLUDEPATH += . / ../../public/STLport-5.1.3/stlport / ###这句一定要放在前面 ../../public/SDL-1.2.13/include / ../../public/common/include / ../../public/qextserialport-1.1/ ../../public/boost-1.37.0/include ================================ 如果库的依赖关系(*.dll)出错,则应用程序会出现报内存的错误,最简单的方法就是把应用程序 所需要的库直接加入环境变量path中,以造成如果库更新,原来拷在应用程序下的库没有及时更新,环境 变更path的设置例子: path += D:/QtDevelop/umpcapp/public/boost-1.37.0/lib; D:/QtDevelop/umpcapp/public/qextserialport-1.1/build 上面对应的库为: boost_system-mgw34-mt-1_37.dll;boost_thread-mgw34-mt-1_37.dll; qextserialport.dll ================================================== 编译成功后,debug下的 exe文件不能生成,请检查.pro文件中,HEADERS与SOURCES参数配置是否有错误, 比如把.h文件加入SOURCES参数中, 把.cpp加入HEADERS参数中. ========================================================== void MapScene::mouseMoveEvent ( QGraphicsSceneMouseEvent * mouseEvent ) { QPointF scenepos; scenepos = mouseEvent->scenePos(); //qDebug()settings()->setAttribute(QWebSettings::PluginsEnabled,true); ================================= listWidget->addItem(new QListWidgetItem(QIcon(":/notepaditem.png"), QFile(files[i]).fileName() )); ========================================================== vector 引用的单元: #include using namespace std; ============================== QString 字符串换行: QString str; str = tr("133"); str.append(tr("
")); 注:br后要加一个空格; ======================================================= Qss 背景透明: QPushButton{ background-color: rgba( 255, 255, 255, 0% ); } ========================================== 打开指定URL地址 QUrl url("http://www.zzwtt.com"); QDesktopServices::openUrl(url); 可以打开任意URL =================================== 窗体置前: QWidget w; w.setWindowFlags(Qt::WindowStaysOnTopHint); w.show(); ================================================== 窗体不显示在任务栏: setWindowFlags(Qt::Popup) ; ============================== 注:改变*.h的内容,编译时会没有编译过程,只有改变*.cpp才会进行编译; ================================================ 编译win32 中的 dll工程配置方法(以skypebackend为例): 因为工程中的代码全是标准C++的代码,所以编译方式跟QT有点不一样, Project-properties...-Project settings页中的"This is a custom Makefile"前面的方框不要勾选; Project-properties...-Build targets 右边中的"Type"设置为"Console application"(skypebackend为控制台程序) Project-build options-Linker settings页,设置Link libraries内容为:(win32库文件) ../../../../MinGW/lib/librpcdce4.a ../../../../MinGW/lib/librpcns4.a ../../../../MinGW/lib/librpcrt4.a ============== 按回车定位到下一焦点: connect(lineEdit1, SIGNAL(returnPressed()), lineEdit2, SLOT(setFocus())); ======================================= 项目翻译 DEMO: #include #include #include int main( int argc, char **argv ) { QApplication app( argc, argv ); QTranslator translator( 0 );//Creates a QTranslator object without a parent translator.load( "ttl_zh-cn", "." );//Try to load a file called ttl_zh-cn.qm app.installTranslator( &translator );//Add the translations from ttl_zh-cn.qm to the pool of translations QPushButton hello( QPushButton::tr( "Hello world!" ), 0 ); app.setMainWidget( &hello ); hello.show(); return app.exec(); } 1.使用qmake -project生成.pro文件; 2.在.pro文件中加上如下语句: TRANSLATIONS = ttl_zh-cn.ts 3.运行如下命令: lupdate ttl.pro 生成ttl_zh-cn.ts文件;(PS:.ts的名字来自“翻译源”(translation source)) 4.运行如下命令: linguist ttl_zh-cn.ts 这时候会弹出一个图形界面工具: 1)单击左边窗口的QPushButton 2)双击中间窗口的helloworld!这时会弹出一个对话框,在Translation下输入:你好世界! 3)单击工具栏的Done and Next按钮(这个时候QPushButton的前面会变成绿色的对号)显示翻译完成 4)然后File->Release,这个是生成.qm文件(.qm来自“QT消息”Qt message),保存到当前目录下 也可以使用命令release ttl_zh-cn.ts来生成.qm文件的。 5)点击linguist“X”退出窗口,这个时候会提示保存ttl_zh-cn.ts文件,单击save,完成操作。 这一步的目的是把“你好世界!”来替代ttl_zh-cn.ts中的“unfinished”,这个只要了解就可以了,有兴趣的可以去看看QT参考文档。 5.运行如下命令: qmake ttl.pro 6.运行如下命令: make 7.运行如下命令: ./ttl 这个时候你会发现按钮是显示的是:“你好世界!” 而不是“helloworld!” PS:lupdate和lrelease命令都可以带参数-verbose,这样会显示一些提示信息。这个 参数是可选的。 通过上面的步骤可以完成正常的翻译,但对象QLineEdit的右键菜单显示的还是英文,解决方法: 把Qt/translations目录下的qt_zh_CN.ts里面的内容全部拷到自己项目ts文件的后面就可以了(也就是把两个ts文件合并) ============================================================ ==================================================== 4字节空间存INT类型: #define USERGROUP_WIDTH 5; char buff[5]; int groupid = atoi(groupId.trimmed().toAscii().data()); //得到GroupID的int值 char* gid = (char*)(&groupid); //将groupid转化为char*类型 memcpy(buff, gid, USERGROUP_WIDTH-1); char p[4]; memset(buff, 0, USERGROUP_WIDTH); memcpy(buff, p, USERGROUP_WIDTH-1); int gid = *((int*)(&buff)); ================================== 错误信息:redefinition class... 请核对 #ifndef IGPSINTERACTION_H_INCLUDED #define IGPSINTERACTION_H_INCLUDED 上面两行中的名称是否一样(出现过第两行中最后一个"D"没掉, 找了N久才查出问题, 汗~~~) 另一原因是变量定义不可放在.h文件中,如下 struct mystruct{ ... }; 是一个变量 (不可放在.h文件中实现) typedef struct MyStruct{ .... }mystruct; 其中 MyStruct是一种类型,而mystruct是一个变量 标准用法 在.h文件中 typedef struct MyStruct{ .... }; 在.cpp中定义变量 struct MyStruct mystruct; ========================================================= std::string 转QString: std::string groupName = 'abcdef'; const char *groupNameCh = groupName.c_str(); QString tmpStr = QObject::tr(groupNameCh); ================================================= 窗体在执行destory() 时,qapp对象就已经退出啦; =============================================== gsoap 项目中的错误:multiple definition of `namespaces' 解决方法:用gsoap中的工具生成的 nsmap文件(#include "UMPCServer.nsmap")引用不能写在.h中,应该要写在.cpp文件中; a.cpp: #include "UMPCServer.nsmap" 上面的写法是正确的,不能写在a.h文件中,否则就会报错 ================ 删除TreeWidget结点: void MainWindow::clearTreeWidget() { while ( treeWidget->topLevelItemCount() > 0 ) { QTreeWidgetItem *parentItem = treeWidget->takeTopLevelItem(0); QList list = parentItem->takeChildren (); for (int j = 0; j < list.size(); j++) { QTreeWidgetItem *childItem = list.at(j); delete &nodeItemData(childItem); delete childItem; } delete &nodeItemData(parentItem); delete parentItem; } } ======================================================= IGPSNestData* resolveRecord(const QSqlRecord &record,const DataType &dateType ) error: expected `,' or `...' before '&' token 解决方法 #include =========================================================== GpsSideBar::IGPSNestData* GpsSideBar::resolveRecord(const QSqlRecord &record,const GpsSideBar::DataType &dateType ); { } error: declaration of `GpsSideBar::IGPSNestData* GpsSideBar::resolveRecord(const QSqlRecord&, const GpsSideBar::DataType&)' outside of class is not definition 解决方法:去掉函数头最后的";" GpsSideBar::IGPSNestData* GpsSideBar::resolveRecord(const QSqlRecord &record,const GpsSideBar::DataType &dateType ) { } ============================================================ QTreeWidget/QTreeView 中的CheckStatus状态的级联更新 void GpsSideBar::on_treeWidget_itemChanged ( QTreeWidgetItem * item, int column ) { if (!item || column != 0) return; Qt::CheckState state = item->checkState(0); QTreeWidgetItem *parent = item->parent(); if (parent) { int number = 0; int partiallyCheckedNum = 0; for (int row = 0; row < parent->childCount(); ++row) { if (parent->child(row)->checkState(0) == Qt::Checked) ++number; if (parent->child(row)->checkState(0) == Qt::PartiallyChecked) ++partiallyCheckedNum; } if (number == 0) { if (parent->checkState(0) != Qt::Unchecked && partiallyCheckedNum == 0) parent->setCheckState(0, Qt::Unchecked); else if (parent->checkState(0) != Qt::PartiallyChecked && partiallyCheckedNum > 0) parent->setCheckState(0, Qt::PartiallyChecked); } else if (number == parent->childCount()) { if (parent->checkState(0) != Qt::Checked ) parent->setCheckState(0, Qt::Checked); } else { if (parent->checkState(0) != Qt::PartiallyChecked ) parent->setCheckState(0, Qt::PartiallyChecked); } } if (item->childCount() > 0) { int row; if (state == Qt::Checked) { for (row = 0; row < item->childCount(); ++row) { if (item->child(row)->checkState(0) != Qt::Checked) item->child(row)->setCheckState(0, Qt::Checked); } } else if (state == Qt::Unchecked ) { for (row = 0; row < item->childCount(); ++row) { if (item->child(row)->checkState(0) != Qt::Unchecked) item->child(row)->setCheckState(0, Qt::Unchecked); } } } } ========================================== 清空QTreeWidget/QTreeView 所有结点(gpssidebar.cpp文件中提取): void GpsSideBar::clearTreeWidget(QTreeWidget *treeWidget) { while ( treeWidget->topLevelItemCount() > 0 ) { QTreeWidgetItem *parentItem = treeWidget->takeTopLevelItem(0); QList list = parentItem->takeChildren (); for (int j = 0; j < list.size(); j++) { QTreeWidgetItem *childItem = list.at(j); delete &GetGPSNestData(childItem); delete childItem; } delete &GetGPSNestData(parentItem); delete parentItem; } } ========================================================== ini配置文件中的字段名是区分大小写的 ========================================================= void MainWindow::contextMenuEvent(QContextMenuEvent *event) { QMenu menu(this); menu.addAction(cutAct); menu.addAction(copyAct); menu.addAction(pasteAct); menu.exec(event->globalPos()); } ================================================== 让 QLineEdit不弹出右键菜单: QLineEdit->setContextMenuPolicy(Qt::NoContextMenu); ========================================= 计算坐标两点间的角度: 第一种方法: double calcAngle(const QPointF& centerPos,const QPoint& pos) { double px1,px2,py1,py2; px1 = centerPos.x(); py1 = centerPos.y(); px2 = pos.x(); py2 = pos.y(); double x = px2 - px1; double y = py2 - py1; double hyp = sqrt(pow(x,2) + pow(y,2)); double cos = x / hyp; double rad = acos(cos); double deg = 180/(M_PI / rad); if (y < 0) { deg = -deg; } else if ((y == 0) && (x <0)) { deg = 180; } deg = deg + 90; if (deg < 0) { deg = deg + 360; } return deg; } 第二种方法: int calcAngle(const double& sx,const double& sy,const double& dx,const double& dy) { double x, y, k1, k2; x = dx - sx; y = dy - sy; if ( (x == 0) && (y == 0) ) { return 0; } if (x == 0) { if ( y < 0) return 0;在X轴上时两种结果 if ( y > 0) return 180; } if ( y == 0) { if ( x > 0 ) return 90;//在Y轴上时两种结果 if ( x < 0) return 270; } k1 = 0; //因为直线(L1)在Y轴上,所以方程为:y=0x+0;即Y=0;斜率为0 k2 = y / x; //直线(L2)的斜率为 y/x,前面已经去除了x=0或y=0的情况 int result = round(atan(fabs(k1 - k2)) * 180 / M_PI); //由于K1=0,所以 a := abs(k1 - k2) / abs(1 + k1 * k2); if ( (x > 0) && (y < 0) ) { result = 90 - result; } else if ( (x > 0) && (y > 0) ) { result = 90 + result; } else if ( (x < 0) && (y > 0) ) { result = 270 - result; } else if ( (x < 0) && (y < 0) ) { result = 270 + result; } return result; } ============================================================== void MainWindow::setCurrentFile(const QString &fileName) { curFile = fileName; if (curFile.isEmpty()) setWindowTitle(tr("Recent Files")); else setWindowTitle(tr("%1 - %2").arg(strippedName(curFile)) .arg(tr("Recent Files"))); QSettings settings("Trolltech", "Recent Files Example"); QStringList files = settings.value("recentFileList").toStringList(); files.removeAll(fileName); files.prepend(fileName); while (files.size() > MaxRecentFiles) files.removeLast(); settings.setValue("recentFileList", files); ======================================= setMouseTracking(true)是打开鼠标移动跟踪,默认情况下只有在鼠标按下后才会发送 QMouseMoveEvent() 事件,打开鼠标移动跟踪后就能够随时发送了. ================================================ QT获取mysql包含中文的值 QString lname2 = QString::fromUtf8(query.value(0).toByteArray()); qDebug()<")<setData(0,Qt::UserRole, qVariantFromValue( int(itemData) ) ); } // 取值 ItemData* GpsSideBar::GetGPSNestData(QTreeWidgetItem *item) { //return qVariantValue(item->data(0,Qt::UserRole)); return reinterpret_cast ( qVariantValue(item->data(0,Qt::UserRole)) ); } =========================================================== 在linux 下运行designer不能正常显示中文的解决方法: 在qtconfig中设置font为Bitstream Charter,然后保存就OK了 ======================================= 移交控制权 qApp.processEvents(); 相当于delphi中的application.processmessage; ================================================== Qt Script Debugger — 用于调试Qt Script的工具,可以单步运行,查看输出等。 Qt文档里有很详细的一篇专门讲这个的,有兴趣的来看下: Qt Script Debugger Manual ============================================= Com 口大于10需经特殊处理: .//COMxx 如 .//COM10 等价于 COM10; ==================================================== 透明的控件的TranslucentBackground属性为true (继承了parent的属性), 而非透明的控件则在代码中强制将TranslucentBackground设为了false, 这样就造就了有意思的结果。 代码片段如下: label = new QLabel(”www.cuteqt.com”); label->setAttribute(Qt::WA_TranslucentBackground, false); //设置为false完全不透明 label->setAutoFillBackground(true); ======================= 怎样将日志输出到文件中 void myMessageOutput( QtMsgType type, const char *msg ) { switch ( type ) { case QtDebugMsg: //写入文件; break; case QtWarningMsg: break; case QtFatalMsg: abort(); } } int main( int argc, char** argv ) { QApplication app( argc, argv ); qInstallMsgHandler( myMessageOutput ); ...... return app.exec(); } qDebug(), qWarning(), qFatal()分别对应以上三种type。 ======================================================= QGraphicsView 的updateSceneRect 有些时候,当你往一个QGraphicsView中添加一个空的QGraphicsScene并且批量地在这个 QGraphicsScene中添加上大量的自定义的图形对象时,会发现QGraphicsView显示出来的图像有些偏移:有足够的空间来显示这些图形,可是有些图形画到QGraphicsView的边缘去了以致于没有完全显示出来。 这是因为当前的消息循环还没有处理完毕,因此 QGraphicsView的槽“updateSceneRect”还没有被调用。这样它的sceneRect没有刷新,就没有将更改过大小的scene 移动到中心点了。 解决办法是在添加完毕图形对象之后立即调用updateSceneRect,使之刷新sceneRect。 ======================================================= QGraphicsView 绘图问题 QGraphicsScene scene; scene.setSceneRect(0, 0, 800, 800); QGraphicsLineItem *line = new QGraphicsLineItem(0, 0, 500, 500); scene.addItem(line); QGraphicsView *view = new QGraphicsView(&scene); 上面这段代码,如果把view作为主窗体在main函数中显示出来,线会正常的画出来. 但一但有其它窗体作为主窗体,比如MainWindow,然后在其构造函数或其它函数中调用这这段代码, view可以显示出来,但线不会被画出来. (无论是作为单独的窗体还是作为MainWindow的 CentralWidget都不会被画出来,看了sample里面的几乎完全一样的代码却正常 解决方法: scene是局部变量,函数结束后被销毁了,应该用 QGraphicsScene *scene = new QGraphicsScene(this); 但问题是为什么main函数中这样用不会出问题? 因为你那个main函数没有结束,这个函数是要到程序结束时结束的,所以那个临时变量没有删除, 这样用就没有问题。其他的函数调用完就结束了。 ================================ ======================= 查出通讯录中代理不能取得焦点的BUG原因:MainWindow 要是继续自QMainWindow或QWidget就 取不了焦点,但如果继承自 QDialog则可以取得焦点 =================================================== 窗体CallingCardEdtFrm(继承自QWidget),在此窗体上创建个组件 QListWidget,QListWidget中的 QListWidgetItem(里面有个QLineEdit编辑组件)的绘制与 显示使用代理实现 class CallingCardEdtDlg:public QDialog //如此继承自QMainWindow或QWidget则QLineEdit获取不了 //焦点并且不能输入,但如果继承自QDialog就没问题了 { Q_OBJECT public: CallingCardEdtDlg(QWidget*); }; CallingCardEdtDlg::CallingCardEdtDlg(QWidget* parent) :QDialog(parent) { CallingCardEdtForm * frm = new CallingCardEdtForm(0); frm->setGeometry(0,0,200,200); QStackedWidget* stackedWidget = new QStackedWidget(0); stackedWidget->addWidget(frm); stackedWidget->setCurrentIndex(0); QGraphicsScene* scene = new QGraphicsScene(); QGraphicsView* view = new QGraphicsView(scene); view->setParent(this); QGraphicsProxyWidget* proxyWidget = new QGraphicsProxyWidget(); proxyWidget->setCacheMode(QGraphicsItem::DeviceCoordinateCache); proxyWidget->setWidget(stackedWidget); scene->addItem(proxyWidget); //view->resize(200,200); view->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform); //view->setBackgroundBrush(QPixmap(":/No-Ones-Laughing-3.jpg")); view->setCacheMode(QGraphicsView::CacheBackground); view->setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate); view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); view->setBackgroundBrush(QColor("#151C28"));// } ====================================================================== 事件原型申明中的类型定义不能加默认值 ============================================ QPainterPath 画出的图形会闪烁的问题: 用下面的写法画出的图形会闪烁 class MyClass: public QWidget { public: MyClass(QWidget*); private: QPainterPath* route; void paintEvent(QPaintEvent*e); }; MyClass::MyClass() { route = new QPainterPath(); } void MyClass::paintEvent( QPaintEvent*e) { QPainter *painter = new QPainter(this); //画校正图形 int insideR = 30; int outsideR = 50; QColor insideColor(237,29,12); //内圆线条颜色 QColor outSideColor(237,29,12); //外圆线条颜色 QColor lineColor(237,29,12); //直线颜色 QColor insideBrushColor(255,0,0,25);//内圆画刷颜色,最后的参数代表透明度( 0(完全透明)-100(不透明) ) QColor outsideBrushColor(255,0,0,50);//外圆画刷颜色,最后的参数代表透明度( 0(完全透明)-100(不透明) ) //QPainterPath path; route->moveTo(insideR,0); route->lineTo(outsideR,0); route->arcTo(0-outsideR,0-outsideR,outsideR*2,outsideR*2,0,180); route->lineTo(0-insideR,0); route->arcTo(0-insideR,0-insideR,insideR*2,insideR*2,0,180); route->moveTo(0-insideR,0); route->lineTo(0-outsideR,0); route->arcTo(0-outsideR,0-outsideR,outsideR*2,outsideR*2,180,180); route->lineTo(insideR,0); route->arcTo(0-insideR,0-insideR,insideR*2,insideR*2,180,180); painter->setPen(Qt::NoPen); painter->setBrush(outsideBrushColor); painter->drawPath(*route); painter->setBrush(Qt::NoBrush); painter->setPen(outSideColor); painter->drawEllipse( QPointF(0,0),outsideR,outsideR ); painter->setBrush(insideBrushColor); painter->setPen(insideColor); painter->drawEllipse( QPointF(0,0),insideR,insideR ); painter->setPen(lineColor); QPoint p1(0, 0- outsideR - 10 ); QPoint p2(0, outsideR + 10 ); painter->drawLine(p1,p2); painter->rotate(90); painter->drawLine(p1,p2); painter->rotate(-90); delete painter; } 如下用下面的写法则不会闪烁: void MyClass::paintEvent( QPaintEvent*e) { QPainter *painter = new QPainter(this); //画校正图形 int insideR = 30; int outsideR = 50; QColor insideColor(237,29,12); //内圆线条颜色 QColor outSideColor(237,29,12); //外圆线条颜色 QColor lineColor(237,29,12); //直线颜色 QColor insideBrushColor(255,0,0,25);//内圆画刷颜色,最后的参数代表透明度( 0(完全透明)-100(不透明) ) QColor outsideBrushColor(255,0,0,50);//外圆画刷颜色,最后的参数代表透明度( 0(完全透明)-100(不透明) ) QPainterPath path; path.moveTo(insideR,0); path.lineTo(outsideR,0); path.arcTo(0-outsideR,0-outsideR,outsideR*2,outsideR*2,0,180); path.lineTo(0-insideR,0); path.arcTo(0-insideR,0-insideR,insideR*2,insideR*2,0,180); path.moveTo(0-insideR,0); path.lineTo(0-outsideR,0); path.arcTo(0-outsideR,0-outsideR,outsideR*2,outsideR*2,180,180); path.lineTo(insideR,0); path.arcTo(0-insideR,0-insideR,insideR*2,insideR*2,180,180); painter->setPen(Qt::NoPen); painter->setBrush(outsideBrushColor); painter->drawPath(path); painter->setBrush(Qt::NoBrush); painter->setPen(outSideColor); painter->drawEllipse( QPointF(0,0),outsideR,outsideR ); painter->setBrush(insideBrushColor); painter->setPen(insideColor); painter->drawEllipse( QPointF(0,0),insideR,insideR ); painter->setPen(lineColor); QPoint p1(0, 0- outsideR - 10 ); QPoint p2(0, outsideR + 10 ); painter->drawLine(p1,p2); painter->rotate(90); painter->drawLine(p1,p2); painter->rotate(-90); delete painter; } ================================================ 如何让QT程序只运行一次: 以下代码在Ubuntu,win下测试通过: #include #include #include #include #include int main(int argc, char *argv[]) { QApplication app(argc, argv); QSystemSemaphore sema("JAMKey",1,QSystemSemaphore::Open); sema.acquire();//在临界区操作共享内存 SharedMemory QSharedMemory mem("SystemObject");//全局对象名 if (!mem.create(1))//如果全局对象以存在则退出 { qDebug()<<<" 所在文件:"<<<"所在行:"userinfo = userInfo; } ================================================== 自定义事件方法: a.h: #include "event.h" typedef void ( EventDelegater::*SetWidgetParent )(QWidget*,QString ); class test { public: Event OnSetWidgetParent; private: inline void invokeSetWidgetParent(QWidget *parentWidget,QString widgetName); }; a.cpp: inline void test::invokeSetWidgetParent(QWidget *parentWidget,QString widgetName) { if ( !OnSetWidgetParent.m_EventList.empty() ) { // 循环事件列表 Event< SetWidgetParent >::EventIterator iter; for ( iter = OnSetWidgetParent.m_EventList.begin(); iter != OnSetWidgetParent.m_EventList.end(); ++iter ) { // 调用事件 InvokeEvent( parentWidget, widgetName ); } } //另一方法:INVOKEEVENT(SetWidgetParent,OnSetWidgetParent, (parentWidget,widgetName)); } 触发事件: invokeSetWidgetParent(NULL,QString()); 绑定事件方法: mainwindow.cpp: test->OnSetWidgetParent.Bind(this, &MainWindow::setWidgetParent); iSMS->OnSMSStateChanged.Bind(this, &WriteMsgWidget::SMSStateChanged); iMMS->OnMMSStateChanged.UnBind(this, &WriteMsgWidget::mmsStateChanged); ================================================ 自定义宏的用法: *.pro DEBUGSAVETOFILE = 1 isEmpty(DEBUGSAVETOFILE){ win32:debug { CONFIG += console } } else{ DEFINES += __DEBUGSAVETOFILE__ } main.cpp: #ifdef __DEBUGSAVETOFILE__ #pragma message( "__DEBUGSAVETOFILE__ is defined.") qInstallMsgHandler( messageOutput ); #else #pragma message("win32:debug is defined.") #endif =================================================== qss 收集: Setting QObject properties From 4.3 and above, any designable Q_PROPERTY can be set using the qproperty- syntax. For example, MyLabel { qproperty-pixmap: url(pixmap.png); } MyGroupBox { qproperty-titleColor: rgb(100, 200, 100); } QPushButton { qproperty-iconSize: 20px 20px; } If the property references an enum declared with Q_ENUMS, you should reference its constants by name, i.e., not their numeric value. ============================================ 类成员函数里定义的临时指针不能做为参数传递; 函数里取得的指针无法返回到外面; groupmanage.h: class GroupManage { private: /// 组在线数据 /** . */ class OnLineData { public: IGPSNav* iGpsNav; /**< GPS聊天接口 */ int groupId; /**< 组ID */ }; QList onLineList; /**< 组在线列表 */ private: ///查找GPS聊天接口 /** @param groupId 组id @param gpsNav(返回值) 只有在查到时才返回指针 @return true:查找到 false: 未查找到 */ bool findGpsNav(int groupId,unsigned int & gpsNav); //正确的写法:返回对象指针地址 bool findGpsNav(int groupId,IGPSNav* iGpsNav);//如果是这样写法请注意调用方法 void test(); }; groupmanage.cpp: //查找GPS聊天接口 bool GroupManage::findGpsNav(int groupId,unsigned int & gpsNav) { bool ok = false; for (int i=0; i < onLineList.count() ; i++) { OnLineData* onLineData = onLineList.at(i); if ( onLineData->groupId == groupId ) { ok = true; gpsNav = (unsigned int)(onLineData->iGpsNav); break; } } _EDEBUG("findGpsNav gpsNav="<< onLineList.count() ; i++) { OnLineData* onLineData = onLineList.at(i); if ( onLineData->groupId == groupId ) { ok = true; iGpsNav = onLineData->iGpsNav; break; } } _EDEBUG("findGpsNav gpsNav="<<<< ============================ Err: "A does not name a type" class B{ public: A hello; B(){} ~B(){} }; class A{ public: A(){} ~A(){} }; I get the error "A does not name a type" when declaring A hello. 解决方法 在 calss B前加个calss A ; ====================================== 要用到模板时,请把定义文件与实现文件写在同一个文件*.hpp中 ============================================================== 定时器: int timeOutTimeId; timeOutTimeId=0; timeOutTimeId = startTimer(1000); if (timeOutTimeId != 0) { killTimer(timeOutTimeId); timeOutTimeId = 0; } void timerEvent(QTimerEvent *event) { if (event->timerId() == timeOutTimeId ) { emit loginStatus(2); killTimer(timeOutTimeId); timeOutTimeId = 0; } } =========================== QMYSQL3: Unable to fetch data Mysql安装目录bin下的库文件 libmySQL.dll 的问题:mysql5.1的库有问题,用mysql5.0的可以 =============================== QString 与QByteArray的转换 QString str; QByteArray byteAry; byteAry = str.toUtf8(); str = QString::fromUtf8(byteAry.data()); ======================================= win32: LIBS += -lws2_32 / -lboost_system-mgw34-mt-1_37 / -lboost_thread-mgw34-mt-1_37 / -lboost_filesystem-mgw34-mt-1_37 / -liconv.dll / -lrasapi32 / -lqjson / -llog4cpp / -lwsock32 注:-llog4cpp 这行必须要放在-lwsock32 前一行 log4cpp的封装单元在public目录下abclog.h 用法: ABCLog::log.error("你好"); ABCLog::log.error(QObject::tr("测试打印Qstring").toUtf8().data()); ABCLog::log.debug("debug你好"); ABCLog::log.info("info"); ABCLog::log.info("%s:%s","你好","daemon"); ABCLog::log.info("%s:%s",QObject::tr("Qstring打印").toUtf8().data(),"daemon"); ABCLog::log.error(QObject::tr("wq w w w 你人我人000").toUtf8().data()); string str; ABCLog::log.info(str.c_str()); =========================================== 编译出问题:任务管理器中的 mingw32-make.exe进程数一直增加 解决方法:请检查系统时间是否有错误 ====================================================== 模板内定义的 PUBLIC域的类型定义,在其他模块中引用时不认 报错: ../../public/tinyjson/tinyjson.hpp|517|error: expected ';' before 'const'| 解决: 在引用前加: typename 如: json::grammar::object 改: typename json::grammar::object 这个错误是由于编译升级限制变严格引起的 ============================================ string 转 int int errCode; char s_char[16]; string str; sprintf(s_char,"%d",errCode); str = s_char; int 转 string string itemCounts; stringstream sstr(itemCounts); int i; sstr >> i; std::string 相连 可以用连接符 += 结构体 转 char* typedef struct S_FeeItem { char userFeeId[20]; /**< 用户计费id(唯一值) */ char telNum[20] /**< 收费号码 */ }FeeItem; FeeItem* feeItemBody; char* feeItem; string value; for (int i = 0; i < *actualItemCounts; i++ ) { feeItemBody = new(FeeItem); value = obj["data"]["items"][i]["user_fee_id"].get(); strcpy(feeItemBody->userFeeId,value.c_str()); value = obj["data"]["items"][i]["tel_num"].get(); strcpy(feeItemBody->telNum,value.c_str()); memcpy(feeItem+sizeof(FeeItem)*i,(char*)feeItemBody,sizeof(FeeItem)); } char* 转 结构体 typedef struct S_ReceiptsItem { char userFeeId[20]; /**< 用户计费id(唯一值) */ char status[20]; /**< 状态 0 成功 其他 错误 */ char errMsg[60]; /**< 错误信息描述 */ }ReceiptsItem; const int MAX_RECEIPTS = 5; int receiptsCounts = 3; ReceiptsItem receiptsItem[MAX_RECEIPTS]; char* prcp = (char*)&receiptsItem[0]; memcpy(prcp, receiptsItems, sizeof(ReceiptsItem)*receiptsCounts); for(int i=0; i < receiptsCounts; i++) { //receiptsItem[i].userFeeId; } =============================================== 在msys环境下显示中文的写法 std::cout<<(str.c_str()); QString qStr = QString::fromUtf8( str_char ); return qStr; } ==================================================== 错误: PHP Warning: PHP Startup: Unable to load dynamic library '/usr/local/php5/lib/php/extensions/daemonsession.so' - /usr/local/session/lib/libsession.so.1: undefined symbol: _ZTIN5boost7archive17archive_exceptionE in Unknown on line 0 解决: LINUX在 .pro 文件中加入: -lboost_regex -lboost_serialzation ============================================================ 在msys 环境下显示中文的写法 std::cout<<<< data_1 << data_2; mainMap.insert("data",people); QJson::Serializer serializer; QByteArray json = serializer.serialize(mainMap); qDebug()<<"json:" << json; //json: "{ "data" : [ { "mobile_tel" : "13860637885", "sms_id" : 626 }, { "mobile_tel" : "12345653221", "sms_id" : 1000 } ], "op_type" : "sendSms" }" //解析 QJson::Parser parser; bool ok; QVariantMap result = parser.parse (json, &ok).toMap(); if (!ok) { qDebug()<<"An error occurred during parsing"; } qDebug()<<"op_type:"<<<"dataList.count:"<< dataList.size(); i++ ) { QVariantMap data = dataList[i].toMap(); qDebug()<<"sms_id:"<<<";mobile_tel:"<<<"end running of SideBarThread..."; } if ( !isSuspended() ) suspend(); if ( isSuspended() ) resume(); ============================================================== 窗体弹出后,我想让他在任务栏不显示,怎么弄啊 ? setWindowFlags(Qt::Popup) ; ===================================================== 隐藏qt程序的任务栏条 看到QWidget的enum Qt::WindowType 中有 Qt::Tool, Qt::Popup 等类型,这些Widget类型是没有任务栏桌面的!如用它们就OK: QWidget mainwindow; // 没有父窗口哦 mainwindow.setWindowFlags( Qt::Tool | Qt::StaysOnTopHint ); //保持在最前面也是我们需要的 但是用这种 Tool型的Widget,直接使用Close() 方法,是关不掉的(Tool作为工具窗口,一般的关闭事件,系统认为只是隐藏而已,所以不是真正的关闭),如要因此退出应用程序的话,需要重载 QWidget的 close() 函数,在其中加入 QApplication::quit(1) 便可。 小心一个问题:在这期间使用的所有Dialog,需指定一个Parent对象,如若不指定,为0,则作为顶层窗口,一旦这个顶层窗口关闭后(Dialog能够真正的关闭,而不是隐藏),整个程序就会关闭,连带我们之前设定的 Tool 型的QWidget。 要解决这个问题,可以设置QApplication实例的 quitOnLastWindowClosed 为 False,说明在最后一个窗口关闭的时候不关闭应用程序。这样一来,只有调用 QApplication::quit() 静态方法,才能退出程序。 ================================== 用 sql语句实现组合Json串(mysql库) select concat( '[', group_concat( concat( '{"ward_list_id":',cast( ward_list_id as char) ) ,concat( ',"ward_name":"',IFNULL(ward_name,'NULL'),'"' ) ,concat( ',"nick_name":"',IFNULL(nick_name,'NULL'),'"' ) ,concat( ',"ward_group_id":',cast( IFNULL(ward_group_id,'NaN') as char),'}' ) ) , ']') from ward_list where ward_list.ward_list_id in (2,20) ============================================================== 用 sql语句操控memcache (mysql库) Memcached Functions for MySQL select memc_servers_set('192.168.0.101:11211'); select memc_set('eagle_eagle_1','你好' ); select cast( memc_get('eagle_eagle_1') as char ); select memc_delete( 'eagle_eagle_1' ); select memc_set('eagle_eagle_2',1); select memc_increment('eagle_eagle_2'); select cast( memc_get('eagle_eagle_2') as char ); select memc_delete( 'eagle_eagle_2' ); select memc_set_by_key ( 'eagle_eagle_1','name','姓名' ) ; select cast( memc_get_by_key ( 'eagle_eagle_1','name') as char ) ; ================================================== win32: LIBS += . / pro文件中 如果LIBS 配置中含 ./ (其实.代表的是目录)则报"ld.exe cannot find .: Permission denied|" ============================================================= *.pro 文件中定义变量用法 CEGUI_PATH = "E:/game/cegui/build" PROJ_ROOT_PATH = D:/study/umpcapp PROJ_ROOT_PATH += /mmorpg DEPENDPATH += $$PROJ_ROOT_PATH/cegui INCLUDEPATH += $$PROJ_ROOT_PATH/cegui / $$CEGUI_PATH/include win32: QMAKE_LIBDIR += $$CEGUI_PATH/lib ========================================== QSqlQueryModel 最多只能取到256条记录的处理方法: QSqlQueryModel *model QSqlQuery q(sqlText ,conn->db); model->setQuery(q); while (model->canFetchMore()) { model->fetchMore(); } =================================

你可能感兴趣的:(Qt,qt,编程,delete,reference,path,include)