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();
}
=================================

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章