`

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>时,提示下面的错误:
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>("SyncMsg");
connect(gpssyncthread, SIGNAL(syncMsgNotify(SyncMsg)),
this, SLOT(syncMsgEvent(SyncMsg)));
========================================
QList<ItemData*> listItemDatas;

for (QList<ItemData*>::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()<<endl;

有三个插件加载路径 1,应用程序路径;2,QTDIR环境路径,3,加入的路径;
=============================================================


TRACE_LEVEL=5 TRACE_SUBSYS=DB /d/study/umpcapp/umpcapp-dev-1.0.0/debug/gpsapp.exe


===============================================
void DragWidget::mousePressEvent(QMouseEvent *event)
{
QLabel *child = static_cast<QLabel*>(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<QKeyEvent *>(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()<<QString::number(scenepos->x())<<QString::number(scenepos->y())<<endl;
emit mapPosNotify(scenepos.x(), scenepos.y());
QGraphicsScene::mouseMoveEvent(mouseEvent);
}

===========================================================
QWebKit中支持Flash播放的代码(Qt4.5才支持Flash)
webView->page()->settings()->setAttribute(QWebSettings::PluginsEnabled,true);

=================================
listWidget->addItem(new QListWidgetItem(QIcon(":/notepaditem.png"), QFile(files[i]).fileName() ));
==========================================================
vector 引用的单元:
#include <iostream>
using namespace std;
==============================
QString 字符串换行:
QString str;
str = tr("133");
str.append(tr("<br />"));

注: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 <qapplication.h>
#include <qpushbutton.h>
#include <qtranslator.h>


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<QTreeWidgetItem *> 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 <QSqlRecord>

===========================================================
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<QTreeWidgetItem *> 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()<<QObject::tr("lname fromUtf8==>")<<lname2<<endl;

===========================================================
QTreeWidgetItem::setData ( int column, int role, const QVariant & value )用法:

自定义一个类:
class ItemData
{
public:
QString name;
int age;
};
Q_DECLARE_METATYPE(ItemData);
//把数据指针存入结点Data:
void GpsSideBar::setItemData(QTreeWidgetItem * item,ItemData *itemData)
{
//item->setData(0,Qt::UserRole, qVariantFromValue(ItemData(*itemData)) );
item->setData(0,Qt::UserRole, qVariantFromValue( int(itemData) ) );
}
//取值
ItemData* GpsSideBar::GetGPSNestData(QTreeWidgetItem *item)
{
//return qVariantValue<ItemData>(item->data(0,Qt::UserRole));
return reinterpret_cast <ItemData*>( qVariantValue<int>(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 <QApplication>
#include <QSystemSemaphore>
#include <QSharedMemory>
#include <QLabel>
#include <QtDebug>

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()<<mem.errorString();
sema.release();//如果是Unix系统,会自动释放。
return 0;
}
sema.release();//临界区

QLabel label("Demo");
label.show();
return app.exec();//释放栈上的mem对象。
}

=========================================
打印当前代码行所在的文件与行:
qDebug()<<"所在文件:"<<QString(__FILE__);
qDebug()<<"所在行:"<<QString(__LINE__);


=======================================
undefined reference to `qInitResources_gui()'

pro文件中,请注意 "RESOURCES += "不可写成"RESOURCES = ";

============================================================

*.pro : unix: DEFINES += __LINUX__

#ifdef __LINUX__
...
#else
...
#endif
==========================================
取得信号对象指针:
QObject * QObject::sender() const

QToolButton* toolBtn = static_cast<QToolButton*>(sender());
===========================================
函数申明后面带有const 的函数,函数体里所调用的函数的申明后面肯定也要带有 const
否则,编译不过
===================================

请教如何在Qt的pro文件中定义字符串宏
在qtcentre中一位高人的方法得到实现:
DEFINES += SHARE_DIR=///"字符串///"
==============================================================

如果使用OObject::tr("你好")对汉字进行赋值,但使用 qDebug()打印时出现乱码,有可能是*.cpp文件编码
有误,请把*.cpp文件编码改为UTF-8编码;

===================================
error: new types may not be defined in a return type
error: return type specification for constructor invalid
请检查类定义后有没加";"
================================================
win下电脑待机方法:

static HANDLE hToken;
static TOKEN_PRIVILEGES tp;
static LUID luid;
if(::OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,
&hToken))
{
::LookupPrivilegeValue(NULL,SE_SHUTDOWN_NAME,&luid);
tp.PrivilegeCount=1;
tp.Privileges[0].Luid =luid;
tp.Privileges[0].Attributes =SE_PRIVILEGE_ENABLED;
::AdjustTokenPrivileges(hToken,false,&tp,sizeof(TOKEN_PRIVILEGES),NULL,NULL);
}
::SetSystemPowerState(true,true);

==============================
改变QMessageBox的大小:
创建一个QMessageBox:

QMessageBox msgBox(this);
msgBox.setWindowTitle(tr("MailBox Location"));

msgBox.setInformativeText(tr("You must ..... and so on and so forth"));

像这样改变它的大小:

1). msgbox.setGeometry ( int x, int y, int w, int h )

2). msgbox.resize(int w, int h)

结果什么都没有发生。

原因:QMessageBox::showEvent() 强制将其大小改变成了QT认为比较合适的大小。要改变它的大小可使用下面这种方法

class MyMessageBox : public QMessageBox {
protected:
void showEvent(QShowEvent* event) {
QMessageBox::showEvent(event);
setFixedSize(640, 480);
}
};

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/diaopan1985/archive/2009/08/01/4399128.aspx

=====================================================================
QString怎么转换成char

QString str ="123456";
str.toAscii().data(); //this return a char* or const char*
str.toAscii() return a QByteArray

QString Str; //Str = "asdfasdfasdf";
Str->toString().c_str();

====================================================
调用 Q_DECLARE_METATYPE 报以下错
../../../../Qt/src/corelib/kernel/qmetatype.h||In function 'void* qMetaTypeConstructHelper(const T*) [with T = ContactsInfoTabItemData]':|
../../../../Qt/src/corelib/kernel/qmetatype.h|152|instantiated from 'int qRegisterMetaType(const char*, T*) [with T = ContactsInfoTabItemData]'|
src/contactsinfotabitemdata.h|62|instantiated from here|
../../../../Qt/src/corelib/kernel/qmetatype.h|126|error: no matching function for call to 'ContactsInfoTabItemData::ContactsInfoTabItemData()'|

如果报以上相类似的错误,请对构造函数中的每个参数赋初值,下面的写法是错误的
class ContactsInfoTabItemData
{
public:
ContactsInfoTabItemData(QString name,QString caption);
};
Q_DECLARE_METATYPE(ContactsInfoTabItemData);

正确的写法应为:
class ContactsInfoTabItemData
{
public:
ContactsInfoTabItemData(QString name=QString(),QString caption=QString());
};
Q_DECLARE_METATYPE(ContactsInfoTabItemData);

===========================================================
如果程序莫名奇妙的退出,也不报DLL找不到的错误,请仔细检查Main函数体有没直接Return的语句,
以造成不提示,直接退出的错误;
=========================================================================================
在Qt中计算文本的宽度与高度
http://www.cuteqt.com/blog/?p=1029
=======================================

error: incomplete type %u2018nsIDOMComment%u2019 used in nested name specifier
产生此错误的原因:
g++ gives this message if you've forward-declared a type, like this

class MyClass;

and then you try and access one of its members, like maybe:

MyClass::doSomething()

g++ is complaining that it hasn't seen the body of class MyClass yet, so it has no way to know what MyClass::doSomething is.

(In C++ jargon, an "incomplete type" is a type that's been forward-declared but not yet defined.)

===============================================================================
互斥用法:
QMutex mutex;

void GlobalVar::setUserInfo(const GlobalVar::UserInfo &userInfo)
{
QMutexLocker locker(&mutex);
this->userinfo = userInfo;
}
==================================================
自定义事件方法:
a.h:

#include "event.h"

typedef void ( EventDelegater::*SetWidgetParent )(QWidget*,QString );

class test
{
public:
Event<SetWidgetParent> 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-<property name> 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<OnLineData*> 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="<<gpsNav);
return ok;
}
bool GroupManage::findGpsNav(int groupId,IGPSNav* iGpsNav)
{

bool ok = false;
for (int i=0; i < onLineList.count() ; i++)
{
OnLineData* onLineData = onLineList.at(i);
if ( onLineData->groupId == groupId )
{
ok = true;
iGpsNav = onLineData->iGpsNav;

break;
}
}
_EDEBUG("findGpsNav gpsNav="<<iGpsNav);
return ok;
}
void GroupManage::test()
{
IGPSNav* iGpsNav;
unsigned int iGpsNavInt;
bool ok;
ok = findGpsNav(groupId,iGpsNavInt);
iGpsNav = (IGPSNav*)iGpsNavInt;
_EDEBUG("iGpsNav:"<<iGpsNavInt<<iGpsNav); //正常返回

/*--下面的写法指针返回不了
IGPSNav* iGpsNav; //把此句申明放在类的private:下就可以解决问题
bool ok;
ok = findGpsNav(groupId,iGpsNav);
_EDEBUG("iGpsNav:"<<iGpsNavInt<<iGpsNav); //返回的指针为空
*/
}

=============================================================

QPushButton{
background-color: rgba( 255, 255, 255, 50% );
}

透明度50%

===================================
1.问题1: connect函数不存在
对象没有从QObject继承.

2.问題2
采用Event方法连接,在对象方法里启动定时器,在运行时发生:
QT timers cannot be started from another thread
解决:
采用Signal/Slot并且连接方式采用 Qt::QueuedConnection

3.利用Signal/Slot删除对象本身:
解决:
采用Signal/Slot并且连接方式采用 Qt::QueuedConnection,这时在另一个对象中就可以删除对象本身了
===========================================================

用qss增加每个菜单项的高度
在用StyleSheet美化QMenu时,如何指定菜单项与快捷键的间距?

QMenu::item {

border: 1px solid transparent;

margin: 0px 2px 0px 2px;

padding: 2px 9px 2px 30px; // Top Right Bottom Left(用这种方式能增加menu中每一行的高度,这就使得在小的触摸屏上进行菜单项的选择的时候,不会那么困难了)

}
=====================
QGraphicsView无法接收到一些widget传过来的消息的处理方法:
bool event ( QEvent * event )
{
if(event->type()==QEvent::MouseButtonPress)
{
QMouseEvent *ke = static_cast<QMouseEvent*>(event);
qDebug()<<"Base Mouse Pressed...."<<ke->pos();
QWidget::event(event); //关键语句
return true;
}
return QGraphicsView::event(event);
};
==========================================================

基于Signal/Slot机制的接口写法:

MyInterface: public QObject{ //QObject子类都可以
Q_OBJECT
public:
explicit MyInterface(QObject* parent = 0); //防止出现异常 显式
virtual ~MyInterface(){}
virtual void myFunc(int i) = 0; //纯虚函数
//....
signals:
void mySignal(int i);
//....
public slots:
virtual void mySlot(){//do nothing};
private:
//...
}

MyImpl:public MyInterface{
Q_OBJECT
public:
MyImpl(parent = 0);
virtual MyImpl(){};
virtual void myFunc(int i){emit mySignal();};
public slots:
void mySlot(){//my code};
}

MyImpl2:public MyInterface{
Q_OBJECT
public:
MyImpl(parent = 0);
virtual MyImpl(){};
virtual void myFunc(int i){emit mySignal();};
public slots:
void mySlot(){//my code};
}

IMyInterface& createMyImpl1(parent = 0)
{
return * new MyImpl1(parent);
}

IMyInterface& createMyImpl2(parent = 0)
{
return * new MyImpl2(parent);
}
========================================================


析构函数 前一定要加 virtual
================================
Aggregation,Composition和Dependency (Star UML)

两个类之间的关系,例如类A和B。
如果B是A成员变量,而且B在A的构造函数中生成(new),那么就是Composition(组合)。
如果B是A成员变量,而且B不在A的构造函数中生成(new),而是在有需要的时候才new,那么就是Aggregation(聚合)。
如果A在某个函数中使用了B作为局部变量,那么就是Dependency(依赖)。

======================================
如果有对某一对象的事件进行Bind操作,记得在自己对象构造时进行UnBind操作;

===========================================
QtDemo中的单例写法

定义文件 menumanager.h:
class MenuManager : public QObject
{
Q_OBJECT
public:
static MenuManager *instance();
virtual ~MenuManager();
private:
MenuManager();
static MenuManager *pInstance;
};

实现文件 menumanager.cpp
#include "menumanager.h"

MenuManager *MenuManager::pInstance = 0; //此句不要少了
MenuManager * MenuManager::instance()
{
if (!MenuManager::pInstance)
MenuManager::pInstance = new MenuManager();
return MenuManager::pInstance;
}
MenuManager::MenuManager()
{
//构造函数
}

MenuManager::~MenuManager()
{
//析构函数
}

调用方法: MenuManager::instance()->


============================
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<T>::object
改: typename json::grammar<T>::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<string>();
strcpy(feeItemBody->userFeeId,value.c_str());

value = obj["data"]["items"][i]["tel_num"].get<string>();
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<<string("TimerThread 线程运行中 ...").c_str()<<std::endl;

====================================================

错误:
process_begin: CreateProcess(NULL, -c "if exist libmysqlpp_ssqls2parse.a del libmysqlpp_ssqls2parse.a", ...) failed.
make (e=2): 系统找不到指定的文件。
mingw32-make.exe: *** [libmysqlpp_ssqls2parse.a] Error 2

解决:
在Makefile文件中
注释下面一句
#SHELL := $(COMSPEC)
增加:
SHELL=cmd.exe
===========================================================
QString 与 std::string互转

string MainWidget::qString2String(QString str)
{
char* str_char = str.toUtf8().data();
string stdStr = str_char;
return stdStr;

}
QString MainWidget::string2QString(string str)
{
char* str_char = const_cast<char*>(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<<string("TimerThread 线程运行中 ...").c_str()<<std::endl;

前提条件是单元文件格式必须是:windows-936

=======================================
70061501

putty
linux上编译server
cd /usr/local/src/tiandi/daemon/server
make clean
qmake -makefile
make

启动
/etc/rc.d/init.d/daemonsd stop

cp ./bin/server /usr/local/daemon/

/etc/rc.d/init.d/daemonsd start

查看进程运行情况

ps -A | grep server
28628 pts/0 00:00:00 server

查看当前所在目录 pwd

==================================
QJson的用法:
QVariantMap mainMap;
mainMap.insert("op_type","sendSms");

QVariantList people;

QVariantMap data_1;
data_1.insert("sms_id", 626);
data_1.insert("mobile_tel", "13860637885");

QVariantMap data_2;
data_2.insert("sms_id", 1000);
data_2.insert("mobile_tel", "12345653221");

people << 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:"<<result["op_type"].toString();
QVariantList dataList = result["data"].toList();
qDebug()<<"dataList.count:"<<dataList.size();
for (int i=0; i < dataList.size(); i++ )
{
QVariantMap data = dataList[i].toMap();
qDebug()<<"sms_id:"<<data["sms_id"].toInt()
<<";mobile_tel:"<<data["mobile_tel"].toString();
}

=======================================================
SuspendableThread 继承自QThread用法
SideBarThread::SideBarThread(QThread *parent)
:SuspendableThread(parent)
{
isFinishRun = false;
suspend();//挂起
gpsInteraction = &createGpsInteraction();
operAct = oaNone;
timeOutTimeId = 0;
}
SideBarThread::~SideBarThread()
{
delete gpsInteraction;
gpsInteraction = 0;
if (timeOutTimeId != 0)
{
killTimer(timeOutTimeId);
timeOutTimeId = 0;
}

isFinishRun = true;
resume();
wait();
}

void SideBarThread::run()
{
//while (!isFinished())
while (!isFinishRun)
{
suspendPoint();//设置挂起点 //suspend //resume
if (isFinishRun)break;
if (operAct == oaGsoapLogin) //登录
{
gsoapLogin();

operAct = oaNone;
suspend();//挂起
}
if (operAct == oaHistoryRoutesQuery) //历史轨迹查询
{
findRoutesHistory();

operAct = oaNone;
suspend();//挂起
}
if (!isFinishRun)
{
msleep(300);
}
}
qDebug()<<"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();
}
=================================

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics