1、QGridLayout QGridLayout包含多個(gè)grid,,它并沒有要求其中的每個(gè)grid的size相同,,通常情況下,每個(gè)grid的size是不同的,。 對(duì)于成員函數(shù)addWidget(widget, fromRow, fromColumn, rowSpan, columnSpan, alignment):rowSpan表示新添加進(jìn)來的widget在垂直方向上跨越或者占據(jù)多少個(gè)grid,。 columnSpan表示新添加進(jìn)來的widget在水平方向上跨越或者占據(jù)多少個(gè)grid。 2,、line edit的input mask 對(duì)一個(gè)line edit設(shè)置了input mask屬性后,,也就限定了輸入字符。一般情況下,需要填寫的字符位置是空白的,,但是,,你可以讓該空白以某個(gè)字符占位,你只需在指定input mask的字符末尾添加“*?”即可,,把‘,?’換為你想用來占位的一個(gè)字符。 3,、利用designer設(shè)計(jì)ui 總體上來說,,先創(chuàng)建各個(gè)控件,然后設(shè)置layout相對(duì)來說好些,。另外,,grid layout對(duì)設(shè)置布局前的窗口布局依賴比較大,即如果設(shè)置grid layout前的布局不同,,則生效后的差別可能較大,。 4、QLabel的buddy屬性 在qt中,,只有QLabel實(shí)現(xiàn)了buddy機(jī)制,。 只有你為QLabel設(shè)置了buddy后,文本中的字符‘&’才能以下劃線顯示(這點(diǎn)與其他widget不同),,并創(chuàng)建了對(duì)應(yīng)的快捷鍵(當(dāng)然,,需要+Alt),然后可以利用快捷鍵迅速的把光標(biāo)定位到該QLabel的buddy中,,例如: QLabel *what = new QLabel("Find &What:"); 該實(shí)例對(duì)應(yīng)快捷鍵Alt+w,。 5、QMouseEvent中的坐標(biāo) QMouseEvent中保存了兩個(gè)坐標(biāo),,一個(gè)是全局坐標(biāo),,當(dāng)然另外一個(gè)是局部坐標(biāo)。 全局坐標(biāo)(globalPos())即是桌面屏幕坐標(biāo)(screen coordinates),,這個(gè)跟windows下的調(diào)用getCursorPos函數(shù)得到的結(jié)果一致。 局部坐標(biāo)(pos())即是相對(duì)當(dāng)前active widget的坐標(biāo),,左上角坐標(biāo)為(0,, 0)。 補(bǔ)充一個(gè)公式: this->mapFromGlobal(this->cursor().pos()) = event.pos() 6,、鼠標(biāo)跟蹤 在qt中,,鼠標(biāo)跟蹤對(duì)應(yīng)函數(shù)mouseMoveEvent。但是,,默認(rèn)情況下他并不能如期象你想象的那樣響應(yīng)鼠標(biāo)的移動(dòng),。此時(shí),你只需在合適的位置調(diào)用一下函數(shù)setMouseTracking(true)即可,。 默認(rèn)情況下,,mouseMoveEvent響應(yīng)你按下鼠標(biāo)的某個(gè)鍵(拖動(dòng),,但不局限于左鍵拖動(dòng))的鼠標(biāo)移動(dòng)。 7,、鼠標(biāo)左鍵拖動(dòng)和左鍵點(diǎn)擊的判斷 鼠標(biāo)左鍵點(diǎn)擊很容易判斷,,一般就是在重寫mousePressEvent函數(shù),示例如下: void XXXWidget::mousePressEvent(QMouseEvent *event) { if(event->button() == Qt:leftButton) { // todo ... } } 左鍵拖動(dòng)的判斷一般放在mouseMoveEvent函數(shù)中,,但是你不能向上例一樣來判斷,,因?yàn)樵摵瘮?shù)的event參數(shù)總是返回Qt::NoButton。你可以這樣做: void XXXWidget::mouseMoveEvent(QMouseEvent *event) { if(event->buttons() & Qt:leftButton) { // todo ... } } 8,、窗口有一個(gè)子窗口,,子窗口隨著父窗口最小化而最小化的實(shí)現(xiàn): child = new QWidget(parent); child->setWindowFlags(Qt::Window); 但是,如果父子窗口都顯示的話,,此時(shí)銷毀父窗口,,子窗口依然顯示;然后關(guān)閉子窗口,,才算完全關(guān)閉了整個(gè)窗口,。理想的做法是這樣的: child = new QWidget(parent); child->setWindowFlags(Qt::Window | Qt::SubWindow); 9、解決中文亂碼問題 //解決中文亂碼問題 QTextCodec::setCodecForTr(QTextCodec::codecForName("GB2312")); QTextCodec::setCodecForLocale(QTextCodec::codecForName("GB2312")); QTextCodec::setCodecForCStrings(QTextCodec::codecForName("GB2312")); 10,、實(shí)現(xiàn)多窗體切換,。 信號(hào)通訊方法(參數(shù)1事件響應(yīng)對(duì)象,參數(shù)2響應(yīng)事件,,參數(shù)3本實(shí)例對(duì)象指針,,參數(shù)4響應(yīng)方法) connect(this->ui->butSumbie, SIGNAL(clicked()), this, SIGNAL(send1())); 信號(hào)通訊方法(參數(shù)1事件響應(yīng)對(duì)象,參數(shù)2響應(yīng)事件,,參數(shù)3本實(shí)例對(duì)象指針,,本實(shí)例對(duì)象執(zhí)行方法) connect(this->ui->butSumbie, SIGNAL(clicked()), this, SLOT(close())); 事件中調(diào)用說明: 信號(hào)通訊方法(參數(shù)1事件響應(yīng)對(duì)象,參數(shù)2響應(yīng)事件,,參數(shù)3本實(shí)例對(duì)象指針,,參數(shù)4響應(yīng)方法) MyWidget w; 執(zhí)行權(quán)限交給主窗體 app.setMainWidget(&w); 11、獲取當(dāng)前執(zhí)行程序路徑:QCoreApplication::applicationDirPath() 12,、獲取當(dāng)前執(zhí)行程序文件夾下全部文件內(nèi)容并且保存到comboBox中,。 QDir dir(QCoreApplication::applicationDirPath()); 通過QDir獲取目錄下全部文件與文件夾 QFileInfoList qFilelist = dir.entryInfoList(); for(int i=0;i<qFilelist.count();i++) { //判斷獲取到的名稱是文件 if(qFilelist.value(i).isFile()) ui->comboBox->addItem(qFilelist.value(i).fileName(),i); } 13、文件讀取實(shí)現(xiàn)內(nèi)容實(shí)現(xiàn)代碼,。 QFile file(ui->comboBox->itemText(index)); if(file.open(QIODevice::ReadOnly))//以只讀方式打開文件 { FileName = ui->comboBox->itemText(index); QTextStream ts(&file); QTextCodec *codec=QTextCodec::codecForName("GBK"); ts.setCodec(codec); ui->textEdit->setText(QString::null); QString line; do{ line = ts.readLine(); if(!line.isNull()) line+="\n"; ui->textEdit->insertPlainText(line); } while (!line.isNull()); file.close(); } 14,、文件寫入實(shí)現(xiàn)代碼段 QFile file(this->FileName); if(file.open(QIODevice::ReadWrite))//以讀寫方式打開文件 { QTextStream qts(&file); QTextCodec *codec=QTextCodec::codecForName("GBK"); qts.setCodec(codec); QString text = ui->textEdit->document()->toPlainText(); qts<<text;//寫入到文件中。 qts.flush();//執(zhí)行寫入 file.close(); } 15,、數(shù)據(jù)庫QSqlQueryModel類使用意見SqlServer數(shù)據(jù)庫連接,。 ui->setupUi(this); db = QSqlDatabase::addDatabase("QODBC");//定義數(shù)據(jù)庫連接類型。db對(duì)象在執(zhí)行QSqlQueryModel綁定中一直必須是開啟狀態(tài)并且要可見否則無數(shù)據(jù)內(nèi)容顯示。 db.setDatabaseName(QString("DRIVER={SQL Server};" "SERVER=%1;DATABASE=%2;UID=%3;PWD=%4") .arg("127.0.0.1") .arg("Northwind") .arg("sa") .arg("sa")); db.open(); QSqlQuery query(db);//可以執(zhí)行查詢與刪除修改添加操作對(duì)象,。 query.exec("select top 10 * from dbo.Orders"); if(query.numRowsAffected() == -1) { QMessageBox::about(this,"234","234"); } QSqlQueryModel *model = new QSqlQueryModel; ui->tableView->setWindowTitle("model"); model->setQuery("select top 10 * from dbo.Orders"); ui->tableView->setModel(model); ui->tableView->show(); 16,、例用QTableWidget實(shí)現(xiàn)表格樣式自定義顯示結(jié)構(gòu)。 QSqlDatabase db; db =QSqlDatabase::addDatabase("QODBC"); db.setDatabaseName(QString("DRIVER={SQL Server};" "SERVER=%1;DATABASE=%2;UID=%3;PWD=%4") .arg("192.168.0.16") .arg("Northwind") .arg("sa") .arg("sa")); db.open(); QSqlQueryModel *model=new QSqlQueryModel(this); model->setQuery("select * from EmployeeTerritories where EmployeeID<4"); QStringList List; List.push_back("aa");List.push_back("bb");setColumnCount(2);//設(shè)置字段名 setHorizontalHeaderLabels(List);//命名字段 for(int i=0;i<model->rowCount();i++) { QString s; s=model->record(i).value("EmployeeID").toString(); QPushButton *LineEdit1=new QPushButton(s);//綁定在表格中的控件類型 insertRow(i); setCellWidget(i,0,LineEdit1); } db.close(); 17,、實(shí)現(xiàn)不規(guī)則窗體顯示,。 //自定義不規(guī)則窗體 QPalette p = palette(); QPixmap img("a.jpg"); //窗體掩碼圖定義 //QBitmap mask("mask.png"); p.setBrush(QPalette::Window, QBrush(img)); setPalette(p); //設(shè)置掩模圖 //setMask(mask); setWindowFlags(Qt::FramelessWindowHint); resize(800, 600); //ui->setupUi(this); 18、重寫鼠標(biāo)控制窗體移動(dòng)事件 //聲明的對(duì)象 QPoint last,pos0;//鼠標(biāo)移動(dòng)控制對(duì)象 //重寫的鼠標(biāo)移動(dòng)事件 void MainWindow::mouseMoveEvent(QMouseEvent *e) { if(e->buttons() & Qt::LeftButton) { //QMessageBox::about(this,"進(jìn)入移動(dòng)","成功進(jìn)入移動(dòng)事件"); QPoint newpos = e->globalPos(); QPoint upleft = pos0 + newpos - last; move(upleft); } } //重寫的鼠標(biāo)按下事件 void MainWindow::mousePressEvent(QMouseEvent *e) { if(e->button()==Qt::LeftButton) { //QMessageBox::about(this,"進(jìn)入按下","成功進(jìn)入按下事件"); last = e->globalPos(); pos0 = e->globalPos() - e->pos(); } } 19,、QT中調(diào)用DLL實(shí)現(xiàn)代碼段 這個(gè)推薦一款小工具 viewdll.exe ,。實(shí)例代碼和工具下面提供下載。將DLL文件直接拖過去,,就直接顯示DLL里的函數(shù)名,。當(dāng)然也不是所有DLL都能顯示。 用QT生成DLL,,直接導(dǎo)出函數(shù)的方法,。 用QTcreator dll向?qū)Ы⒐こ獭0阉?H文件刪除,,在唯一的.CPP文件中編寫你所要導(dǎo)出的函數(shù),,函數(shù)模版 extern "C" __declspec(dllexport) int ShowMessageBox() { char *str = "this is Dll"; cout<<str; return 0; } 直接編譯后,生成DLL文件,。 將dll文件拷貝到你要使用的exe工程中,。這里我的EXE使用的是core類型,沒有使用GUI,。 在新工程的cpp文件中加入 QLibrary myLib("ClassDll.dll");//加載dll文件 typedef void (*MyPrototype)(); MyPrototype myFunction = (MyPrototype) myLib.resolve("ClassDll");//CLASSDLL是函數(shù)名 if (myFunction) myFunction();//調(diào)用的classdll,也就是你的函數(shù)生成dll的文件: //mydll.h extern "C" __declspec(dllexport) int maxfun(int,int); //函數(shù) struct __declspec(dllexport) nNode //結(jié)構(gòu)體 { int x; }; //mydll.cpp #include "mydll.h" extern "C" __declspec(dllexport)int maxfun(int x,int y) { return x+y; } extern "C" __declspec(dllexport)nNode temp={10}; //這里一個(gè)結(jié)構(gòu)體對(duì)象 ///下面是程序調(diào)用dll. #include <qapplication.h> #include <qlibrary.h> #include <qmessagebox.h> int main(int argc,char* argv[]) { QApplication app(argc,argv); struct mynode { int i; }; QLibrary lib("mydll"); mynode* no = (mynode*)lib.resolve("temp"); if(no) { QMessageBox::information(0,"name",QString::number(no->i)); } else QMessageBox::information(0,"name","no==0"); return app.exec(); } 20,、QT中的網(wǎng)絡(luò)編程與實(shí)現(xiàn)。QT中共提供四個(gè)與套按字相關(guān)的類,,分別是: QServerSocket:TCP-based server QSocket: Buffered TCP connection QSocketDevice: Platform-independent low-level socket API QSocketNotifier: Support for socket callbacks 下面介紹使用QT進(jìn)行網(wǎng)絡(luò)編程,,我們使用一個(gè)簡(jiǎn)單的C/S模式網(wǎng)絡(luò)程序說明如何使用QT中的套接字。同時(shí)我們用TCP和UDP兩種協(xié)議實(shí)現(xiàn)這個(gè)程序(該程序客戶端與服務(wù)端各向?qū)Ψ桨l(fā)送一個(gè)字符口串“abc”) 1,、UDP實(shí)現(xiàn) UDP是不連接協(xié)議,,沒有客戶端與服務(wù)端的概念。 1)建立套接字相關(guān)對(duì)象 QSocketDevice *MUReceiveSocket; //套接字對(duì)象 QSocketNotifier *MSocketNotifier; //套接字監(jiān)聽對(duì)象 2)初始化套接字相關(guān)對(duì)象 MUReceiveSocket=new QSocketDevice(QSocketDevice::Datagram); //UDP初始化 QHostAddress MyAddress; QString FakeAddress; FakeAddress = get_eth1_ip(); //取得接口IP MyAddress.setAddress(FakeAddress); MUReceiveSocket->bind(MyAddress,Port); //綁定到指定網(wǎng)絡(luò)接口地址(IP),,指定邏輯端口 MSocketNotifier = new QSocketNotifier(MUReceiveSocket->socket(),QSocketNotifier::Read,0,"MSocketNotifier"); //監(jiān)聽MUReceiveSocket套接字 3)定義用實(shí)現(xiàn)響應(yīng)slot virtual void OnMReceive(); void Client::OnMReceive() { int ByteCount,ReadCount; char *IncommingChar; fprintf(stderr,"Load a piece of Message!\n"); ByteCount=MUReceiveSocket->bytesAvailable(); IncommingChar=(char *)malloc(ByteCount+1); ReadCount=MUReceiveSocket->readBlock(IncommingChar,ByteCount); IncommingChar[ByteCount]=''; fprintf(stderr,“%s“,IncommingChar); //打印接收的字符串 } 4)關(guān)聯(lián)套接字的signal和接收slot connect(MSocketNotifier,SIGNAL(activated(int)),this,SLOT(OnMReceive())); //當(dāng)MSocketNotifier檢測(cè)到MUReceiveSocket活躍時(shí)調(diào)用OnMReceive 5)發(fā)送字符串 char information[20]; strcpy(information,“abc“); MUReceiveSocket->writeBlock(information,length,MyAddress,2201); 2,、TCP實(shí)現(xiàn) TCP的實(shí)現(xiàn)與UDP的實(shí)現(xiàn)大同小異,它是面象連接的協(xié)議,。這里只介紹與UDP不同的地方。 服務(wù)端: 1)套接字對(duì)象的定義 比UDP多定義一個(gè)套接字,,一個(gè)用來監(jiān)聽端口,,一個(gè)用來通信。 QSocketDevice *ServerSocket; QSocketDevice *ClientSocket; QSocketNotifier *ClientNotifier; QSocketNotifier *ServerNotifier; 2)套接字的初始化 QHostAddress MyAddress; QString FakeAddress; FakeAddress = "127.0.0.1"; MyAddress.setAddress(FakeAddress); UINT Port=1234; ServerSocket=new QSocketDevice(QSocketDevice::Stream); ClientSocket=new QSocketDevice(QSocketDevice::Stream); ServerSocket->bind(MyAddress,Port); ServerSocket->listen(20); //20代表所允許的最大連接數(shù) ClienttNotifier = new QSocketNotifier(ClientSocket->socket(),QSocketNotifier::Read,0,"ClientSocket"); ServerNotifier = new QSocketNotifier(ServerSocket->socket(),QSocketNotifier::Read,0,"ServerSocket"); 3)響應(yīng)連接(在定義slot中響應(yīng)) 當(dāng)收到客戶端的連接后,響應(yīng)它,,并以ClientSocket接收: ServerSocket->SetSocket(ClientSocket->socket()); 4)接收信息slot與UDP一致,,這里不在敘述。 客戶端實(shí)現(xiàn): 客戶端的實(shí)現(xiàn)與UDP實(shí)現(xiàn)大同小異,,不同的地方只是客戶端套接字不需要bind端口,,因?yàn)檫B接上服 務(wù)端后TCP會(huì)保持這個(gè)連接,直到通信的結(jié)束,。 操作系統(tǒng):ARM-LINUX QT版本:QT-2.3.2-FOR-LINUX GUI:Qtopia 在LINUX下進(jìn)行網(wǎng)絡(luò)編程,,我們可以使用LINUX提供的統(tǒng)一的套接字接口。但是這種方法牽涉到太多的結(jié)構(gòu)體,,比如IP地址,,端口轉(zhuǎn)換等,不熟練的人往 往容易犯這樣那樣的錯(cuò)誤,。QT中提供的SOCKET完全使用了類的封裝機(jī)制,,使用戶不需要接觸底層的各種結(jié)構(gòu)體操作。而且它采用QT本身的signal- slot機(jī)制,,使編寫的程序更容易理解,。 QT中共提供四個(gè)與套按字相關(guān)的類,分別是: QServerSocket:TCP-based server QSocket: Buffered TCP connection QSocketDevice: Platform-independent low-level socket API QSocketNotifier: Support for socket callbacks 下面介紹使用QT進(jìn)行網(wǎng)絡(luò)編程,,我們使用一個(gè)簡(jiǎn)單的C/S模式網(wǎng)絡(luò)程序說明如何使用QT中的套接字,。同時(shí)我們用TCP和UDP兩種協(xié)議實(shí)現(xiàn)這個(gè)程序(該程 序客戶端與服務(wù)端各向?qū)Ψ桨l(fā)送一個(gè)字符口串“abc”) 1、UDP實(shí)現(xiàn) UDP是不連接協(xié)議,,沒有客戶端與服務(wù)端的概念,。 1)建立套接字相關(guān)對(duì)象 QSocketDevice *MUReceiveSocket; //套接字對(duì)象 QSocketNotifier *MSocketNotifier; //套接字監(jiān)聽對(duì)象 2)初始化套接字相關(guān)對(duì)象 MUReceiveSocket=new QSocketDevice(QSocketDevice::Datagram); //UDP初始化 QHostAddress MyAddress; QString FakeAddress; FakeAddress = get_eth1_ip(); //取得接口IP MyAddress.setAddress(FakeAddress); MUReceiveSocket->bind(MyAddress,Port); //綁定到指定網(wǎng)絡(luò)接口地址(IP),指定邏輯端口 MSocketNotifier = new QSocketNotifier(MUReceiveSocket->socket(),QSocketNotifier::Read,0,"MSocketNotifier"); //監(jiān)聽MUReceiveSocket套接字 3)定義用實(shí)現(xiàn)響應(yīng)slot virtual void OnMReceive(); void Client::OnMReceive() { int ByteCount,ReadCount; char *IncommingChar; fprintf(stderr,"Load a piece of Message!\n"); ByteCount=MUReceiveSocket->bytesAvailable(); IncommingChar=(char *)malloc(ByteCount+1); ReadCount=MUReceiveSocket->readBlock(IncommingChar,ByteCount); IncommingChar[ByteCount]=''; fprintf(stderr,“%s“,IncommingChar); //打印接收的字符串 } 4)關(guān)聯(lián)套接字的signal和接收slot connect(MSocketNotifier,SIGNAL(activated(int)),this,SLOT(OnMReceive())); //當(dāng)MSocketNotifier檢測(cè)到MUReceiveSocket活躍時(shí)調(diào)用OnMReceive 5)發(fā)送字符串 char information[20]; strcpy(information,“abc“); MUReceiveSocket->writeBlock(information,length,MyAddress,2201); 2,、TCP實(shí)現(xiàn) TCP的實(shí)現(xiàn)與UDP的實(shí)現(xiàn)大同小異,,它是面象連接的協(xié)議。這里只介紹與UDP不同的地方,。 服務(wù)端: 1)套接字對(duì)象的定義 比UDP多定義一個(gè)套接字,,一個(gè)用來監(jiān)聽端口,一個(gè)用來通信,。 QSocketDevice *ServerSocket; QSocketDevice *ClientSocket; QSocketNotifier *ClientNotifier; QSocketNotifier *ServerNotifier; 2)套接字的初始化 QHostAddress MyAddress; QString FakeAddress; FakeAddress = "127.0.0.1"; MyAddress.setAddress(FakeAddress); UINT Port=1234; ServerSocket=new QSocketDevice(QSocketDevice::Stream); ClientSocket=new QSocketDevice(QSocketDevice::Stream); ServerSocket->bind(MyAddress,Port); ServerSocket->listen(20); //20代表所允許的最大連接數(shù) ClienttNotifier = new QSocketNotifier(ClientSocket->socket(),QSocketNotifier::Read,0,"ClientSocket"); ServerNotifier = new QSocketNotifier(ServerSocket->socket(),QSocketNotifier::Read,0,"ServerSocket"); 3)響應(yīng)連接(在定義slot中響應(yīng)) 當(dāng)收到客戶端的連接后,,響應(yīng)它,并以ClientSocket接收: ServerSocket->SetSocket(ClientSocket->socket()); 4)接收信息slot與UDP一致,,這里不在敘述,。 客戶端實(shí)現(xiàn): 客戶端的實(shí)現(xiàn)與UDP實(shí)現(xiàn)大同小異,不同的地方只是客戶端套接字不需要bind端口,,因?yàn)檫B接上服 務(wù)端后TCP會(huì)保持這個(gè)連接,,直到通信的結(jié)束,。 21、Qt窗體布局操作 布局中主要的操作有 水平布局, 垂直布局, 打破布局,。 當(dāng)只有一個(gè)控件時(shí),,不能進(jìn)行布局操作。布局操作是多個(gè)控件,,或者對(duì)話框的操縱,。 選擇多個(gè)窗體控件,按住shift鍵,,鼠標(biāo)點(diǎn)擊選取,,右鍵進(jìn)行布局操縱。 當(dāng)選中對(duì)話框主窗體時(shí),,可以進(jìn)行窗體上控件的布局操作,。 該操縱將對(duì)窗體上的控件或者布局進(jìn)行,水平布局或者垂直布局操縱 22,、Qt繪圖模式 Qt助手,,放大縮小,很方便,。 繪圖系統(tǒng) 主要基于三個(gè)類,,QPainter, QPaintDevice, QPaintEngine. QPainter用于執(zhí)行繪圖操作。QPaintDevice使用QPaint進(jìn)行繪圖所使用的二維空間,。QPaintEngine提供了在不同設(shè)備上的 繪圖接口,,被QPainter, QPaintDevice內(nèi)部使用,對(duì)于程序員來說是隱藏的,,只有在創(chuàng)建自己的設(shè)備類型時(shí),,才能用到。 QPainter能用畫筆作圖,,畫文字或者圖形,。 畫 填充 創(chuàng)建設(shè)備 讀寫圖形文件 樣式 QPaintDevice是用于畫圖的設(shè)備的基類。 QPaintDevice的子類有 QWidget, QImage, QPixmap, QGLWidget, QGLPixelBuffer, QPicture and QPrinter,。 23,、CListWidget與CTableWidget編程注意事項(xiàng) 在執(zhí)行CListWidget與CTableWidget等類似的列表控件的Clear操作時(shí),系統(tǒng)經(jīng)常崩潰,,原因分析,。這個(gè)clear操作因?yàn)楦淖兞肆斜淼膬?nèi)容,會(huì)觸發(fā)其它的信號(hào),。特別是下面的兩個(gè)函數(shù),。 CListWidget的函數(shù) void currentItemChanged ( QListWidgetItem * current, QListWidgetItem * previous ) void currentRowChanged ( int currentRow ) CTableWidget的函數(shù)。 void currentCellChanged ( int currentRow, int currentColumn, int previousRow, int previousColumn ) void currentItemChanged ( QTableWidgetItem * current, QTableWidgetItem * previous ) 如果,,在下面的函數(shù)中,,沒有加入信號(hào)參數(shù)檢測(cè),,就很容易出錯(cuò)。主要檢查currentRow 是否大于或者等于0,。current,previous 是否有效,。如果不檢查,,并根據(jù)該參數(shù),調(diào)用了其它的方法,。當(dāng)currentRow =-1; 時(shí),,就會(huì)發(fā)生錯(cuò)誤。 ui.tableWidget->item(row, 0); row=-1時(shí),,調(diào)用就會(huì)產(chǎn)生錯(cuò)誤,。 ui.listWidget->item(row); row=-1時(shí),調(diào)用就會(huì)產(chǎn)生錯(cuò)誤,。 錯(cuò)誤解決方法:加入錯(cuò)誤檢查,, if (row>=0){//其它相關(guān)處理} 24、一個(gè)工程中出現(xiàn)多個(gè)QMainWindow并同時(shí)顯示的方案,。 問題描述: 在一個(gè)CMainWindow CMyWin1的繼承類中,,如果再使用一個(gè)CMainWindow類CMyWin2; 在CMyWin1中使用以下代碼,、 CMyWin2 mw; mw.show () mw 一閃就沒有了。具體原因不明。 定義窗體局部變量: CDataManager *m_pDataMager; 調(diào)用過程如下,,并建立信號(hào)連接,監(jiān)控信號(hào) destryed,,接收道該信號(hào)時(shí),,做一個(gè)槽處理。 if (m_pDataMager) { m_pDataMager->setVisible (true); m_pDataMager->showNormal (); //m_pDataMager-> } else { m_pDataMager = new CDataManager(); connect(m_pDataMager, SIGNAL(destroyed(QObject*)), this, SLOT(after_DataManage_Destoryed(QObject*))); m_pDataMager->setVisible (true); } 在函數(shù)after_DataManage_Destoryed中,,進(jìn)行窗體的delete,,并設(shè)置變量為NULL。 void SeismicRecogn::after_DataManage_Destoryed(QObject *obj) { //QMessageBox::information(this,"Test Box","DataManage_Destoryed!"); if (m_pDataMager) { disconnect(m_pDataMager, SIGNAL(destroyed(QObject*)), this, SLOT(after_DataManage_Destoryed(QObject*))); obj->deleteLater(); m_pDataMager =NULL; } } 25,、資源文件的動(dòng)態(tài)加載 在構(gòu)造函數(shù)中添加如下: QIcon icon; icon.addPixmap(QPixmap(QString::fromUtf8("../resource/well.png")), QIcon::Normal,QIcon::Off); ui.actionLoad->setIcon(icon); tableWidget設(shè)置高度寬帶 ui.tableWidget->setColumnWidth(0,280); ui.tableWidget->setColumnWidth(1,280); for (int i=0;i<10;i++) ui.tableWidget->setRowHeight(i,20); 26,、如何對(duì)LineEdit輸入數(shù)據(jù)進(jìn)行格式限制。 QLineEdit 中對(duì)輸入字符輸入格式的控制通過inputMask與validators實(shí)現(xiàn),。 使用時(shí),,詳細(xì)閱讀2個(gè)的說明。 QIntValidator *vv=new QIntValidator(this); ui.lineEdit->setValidator (vv); 27,、二維圖形框架Graphics View Graphics View框架實(shí)現(xiàn)了模型-視圖結(jié)構(gòu)的圖形管理,,能對(duì)大量的圖元進(jìn)行管理,支持碰撞檢測(cè),、坐標(biāo)變換和圖元組等多種方便的操作,。Graphics View支持事件傳播體系結(jié)構(gòu),,可以使圖元在場(chǎng)景(scene)中得到提高了一倍的精確交互能力。圖元能夠處理鍵盤事件,,鼠標(biāo)按下,、移動(dòng)、釋放和雙擊事 件,,也能跟蹤鼠標(biāo)的移動(dòng),。在Graphics View框架中,通過BSP(二元空間劃分樹,,Binary Space Partionng)來提供快速的圖元查找,,這樣就能實(shí)時(shí)地顯示大場(chǎng)景,甚至上百萬個(gè)圖元,。 Graphics View框架提供基于圖元的模型-視圖編程,,類似于Qt InterView的模型-視圖結(jié)構(gòu),只是這里的數(shù)據(jù)是圖形,。Graphics View框架中包括三個(gè)主要的類:QGraphicsItem, QGraphicsScene 和 QGraphicsView,。 Graphics View為大量定制的2維圖元的管理與交互提供了一個(gè)框架,可以實(shí)現(xiàn)這些圖元的可視化,,并支持縮放和旋轉(zhuǎn),。 28、Graphics View框架繼續(xù)學(xué)習(xí) 主要內(nèi)容:場(chǎng)景 QGraphicsScene 視圖 QGraphicsView 圖元 QGraphicsItem 示例:Examples and Demos >> Graphics View QGraphicsScene是QGraphicsItems的容器,。它與QGraphicsView一起實(shí)現(xiàn)了圖元的可視化,,例如線,矩形,,文本,,以及定制的圖元。QGraphicsScene也提供了以下功能,,讓你高效的確定圖元的位置以及圖元的可視性,。 QGraphicsScene scene; scene.addText("Hello, world!"); QGraphicsView view(&scene); view.show(); 重點(diǎn)示例程序: Diagram Scene //圖元的外接矩形區(qū)域(虛函數(shù)的實(shí)現(xiàn)) QRectF CGeoObjCnoline::boundingRect() const //圖元的繪制路徑(虛函數(shù)的實(shí)現(xiàn)) QPainterPath CGeoObjCnoline::shape() const //圖元的繪制(虛函數(shù)的實(shí)現(xiàn)) void CGeoObjCnoline::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) 29、要想界面一直存在用new創(chuàng)建 用new指針生成,,起作用 private: Ui::cdtestClass ui; QGraphicsScene *scene; QGraphicsView *view; cdtest::cdtest(QWidget *parent, Qt::WFlags flags): QMainWindow(parent, flags) { ui.setupUi(this); scene = new QGraphicsScene(); scene->setSceneRect (-400,-300,800,600); scene->setItemIndexMethod (QGraphicsScene::NoIndex ); scene->addText ("Good"); view = new QGraphicsView(scene); ui.layTest->addWidget(view); view->update(); } 用局部變量不起作用 void cdtest::on_actionTest_triggered() { QGraphicsScene scene; scene.setSceneRect (-400,-300,800,600); scene.setItemIndexMethod (QGraphicsScene::NoIndex ); scene.addText ("Good"); QGraphicsView view(&scene); ui.layTest->addWidget(&view); view.update(); } 指針用局部變量,,使用的時(shí)候new,起作用,。 void cdtest::on_actionTest_triggered() { QGraphicsScene *scene; scene = new QGraphicsScene; scene->setSceneRect (-400,-300,800,600); scene->setItemIndexMethod (QGraphicsScene::NoIndex ); scene->addText ("Good"); QGraphicsView *view; view =new QGraphicsView(scene); ui.layTest->addWidget(view); view->update(); } 30,、QTableView根據(jù)內(nèi)容自動(dòng)調(diào)整列寬行高 1: 使用QTableView自己帶的函數(shù),函數(shù)原型如下: ui.tableWidget->resizeColumnToContents (0); 將第一列根據(jù)內(nèi)容自動(dòng)調(diào)整列寬,。 根據(jù)內(nèi)容自動(dòng)調(diào)整某列的列寬 void QTableView::resizeColumnToContents ( int column ) [slot] Resizes the given column based on the size hints of the delegate used to render each item in the column. 根據(jù)內(nèi)容自動(dòng)調(diào)整所有列的列寬 void QTableView::resizeColumnsToContents () [slot] Resizes all columns based on the size hints of the delegate used to render each item in the columns. 根據(jù)內(nèi)容自動(dòng)調(diào)整某一行的行高 void QTableView::resizeRowToContents ( int row ) [slot] Resizes the given row based on the size hints of the delegate used to render each item in the row. 根據(jù)內(nèi)容自動(dòng)調(diào)整所有行的行高,。 void QTableView::resizeRowsToContents () [slot] Resizes all rows based on the size hints of the delegate used to render each item in the rows. 31、QGraphicsItem中的碰撞檢測(cè)描述 QGraphicsItem是圖元基類,。QGraphics View框架提供了幾種標(biāo)準(zhǔn)的圖元,,如矩形(QGraphicsRectItem,、橢圓(QGraphicsEllipseItem)和文本圖元 (QGraphicsTextItem)等。用戶可以繼承QgraphicItem實(shí)現(xiàn)符合自己需要的圖元,。 QGraphicsItem具有以下功能: 處理鼠標(biāo)按下,、移動(dòng)、釋放,、雙擊,、懸停、滾輪和右鍵菜單事件 處理鍵盤輸入事件 處理拖放事件 分組 碰撞檢測(cè) 圖元有自己的坐標(biāo)系統(tǒng),,也提供場(chǎng)景和圖元、圖元與圖元之間的坐標(biāo)轉(zhuǎn)換函數(shù),。圖元可以包含子圖元,。 要?jiǎng)?chuàng)建自己的圖元,必須首先創(chuàng)建QGrahicsItem的一個(gè)子類,,然后開始實(shí)現(xiàn)他的2個(gè)純虛函數(shù),。一個(gè)是boundingRect(),用于返回圖元繪制所需要的估測(cè)區(qū)域。另一個(gè)是paint,,它實(shí)現(xiàn)實(shí)際的繪圖操縱,。舉例: class SimpleItem : public QGraphicsItem { public: QRectF boundingRect() const { qreal penWidth = 1; return QRectF(-10 - penWidth / 2, -10 - penWidth / 2, 20 + penWidth / 2, 20 + penWidth / 2); } void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,QWidget *widget) { painter->drawRoundedRect(-10, -10, 20, 20, 5, 5); } }; boundingRect函數(shù)有幾個(gè)目的。QGraphicsScene的圖元索引就是建立在boundingRect的基礎(chǔ)上,。 QGraphicsView也使用這個(gè)函數(shù)來從視圖上將不可見的圖元移去,,以及在繪制重疊的圖元時(shí)決定需要重新組織的區(qū)域。另 外,,QGraphicsItem的碰撞檢測(cè)機(jī)制(collision detection)使用boundingRest來提高高效的處理,。更好的碰撞檢測(cè)算法是基于shape函數(shù)的調(diào)用,shape函數(shù)將圖元的形狀的準(zhǔn)確 外觀以QPainterPath返回,。 QGraphicsScene認(rèn)為所有圖元的boundingRect函數(shù)與shape函數(shù)都是不發(fā)生改變的,,除非用戶進(jìn)行通知。如果你想改變一個(gè)圖元的范圍,,必需先調(diào)用prepareGeometryChange以允許QGraphicsScene進(jìn)行更新,。 碰撞檢測(cè)可以通過以下兩種方式實(shí)現(xiàn): 重新實(shí)現(xiàn)shape函數(shù)返回一個(gè)準(zhǔn)確的圖元外觀形狀,依賴collidesWithItem函數(shù)進(jìn)行缺省的碰撞檢測(cè),,如果形狀非常的復(fù)雜,,該檢測(cè)將是非常耗時(shí)的。 重新實(shí)現(xiàn)collidesWithItem函數(shù),,為自己的定制圖元編寫碰撞檢測(cè)算法,。 對(duì)于多點(diǎn)成線的圖元可以使用下面的方式返回shape。 QPainterPath path; //直線的繪制路徑 if (m_pointList.count()>0) { int iSize; iSize = m_pointList.size(); path.moveTo (m_pointList[0]); for(int i=1;i<iSize/2;i++) { path.lineTo (m_pointList[i*2]); } for(int i=iSize/2;i>=1;i--) { path.lineTo (m_pointList[i*2-1]); } path.closeSubpath(); } return path; 32,、sql中二進(jìn)制文件通過QByteArray讀寫 從數(shù)據(jù)庫到文件 QSqlQuery myquery( *pDatabase); QByteArray myba; if(myquery.exec(sql)) { QSqlRecord myrecord = myquery.record(); if (myquery.next()) { myba = myquery.value(myrecord.indexOf("Settings")).toByteArray();//讀取二進(jìn)制對(duì)象 } } else { initBoundary(); return false; } QFile mybfile(MapDataFilename); if (!mybfile.open(QIODevice::WriteOnly)) { initBoundary(); return false; } mybfile.write (myba); mybfile.close(); 從文件到數(shù)據(jù)庫 //將文件存入數(shù)據(jù)庫 QByteArray mapData; QFile file(MapDataFilename); if (!file.open(QIODevice::ReadOnly)) return false; mapData = file.readAll(); file.close(); QSqlDatabase* pDatabase = CAccessController::getInstance()->getAccesser(g_dbXMLFilePath); if (pDatabase ==0 ) { // QMessageBox::information(this, "Error", CAccessController::getInstance()->lastError()); return false; } QSqlQuery query( *pDatabase); query.prepare("update p_project SET Settings = :set where ID_P = :idp"); query.bindValue (":set",mapData); query.bindValue (":idp",CMainConfig::CurProjectID); bool bRtn = query.exec(); if (!bRtn) { QSqlError er =query.lastError (); QString ss= er.text(); return false; } 33,、QGraphicsView放大縮小中心屬性分析 將下面的函數(shù)注釋掉,,是resize,不發(fā)生縮放,。 void CBaseMapForm::resizeEvent ( QResizeEvent * event ) { //m_view->doZoomAll(); } QMatrix可以直接進(jìn)行文件存儲(chǔ),。 << >>。 34,、幫助文件的調(diào)用執(zhí)行問題 幫助文件安裝制作: 取得當(dāng)前可執(zhí)行程序的路徑 QString strUrl=QApplication::applicationDirPath () ; strUrl=QString("file:///%1/help.htm").arg (strUrl) 用客戶機(jī)的瀏覽器,,打開網(wǎng)頁 desktopServices.openUrl(qqq); 35、最簡(jiǎn)單的圖形顯示控件QLabel imageLabel = new QLabel; imageLabel->setWordWrap(true); imageLabel->setAlignment(Qt::AlignCenter); imageLabel->setPixmap(QPixmap(":/images/image.png")); QPixmap的伸縮 ui.lblImage->setPixmap(pixmap.scaled(ui.lblImage->size()-QSize(40,40),Qt::KeepAspectRatio, Qt::FastTransformation)); 36,、取得QTableView的特定行,,特定列的數(shù)據(jù) QModelIndex index = ui.tableView->currentIndex(); if (!index.isValid()) { QMessageBox::information (NULL,"提示","請(qǐng)先選擇一行數(shù)據(jù)。"); return; } int iRow; iRow = index.row(); QAbstractItemModel* model = ui.tableView->model(); //取得層數(shù)據(jù)庫的數(shù)據(jù)表名 index = model->index(iRow,1,QModelIndex()); QString strHorizonName; strHorizonName = index.data().toString(); 37,、qt下獲得屏幕的分辨率 在Qt中提供了QDesktopWidget類,提供屏幕的有關(guān)信息. 可以這么作: QDesktopWidget *d=QApplication::desktop(); int width=d->widht(); //屏幕的寬度 int height=d->height(); //屏幕的高度 或者簡(jiǎn)寫如下: int width=QApplication::desktop()->width(); int height=QApplication::desktop()->height(); 38,、干掉QT窗體的標(biāo)題欄。,。 setWindowFlags(Qt::FramelessWindowHint); 39,、設(shè)置QT按鈕為透明。 //就是這句能夠?qū)崿F(xiàn)透明,,真是意外的發(fā)現(xiàn),,希望對(duì)一些學(xué)習(xí)的朋友有點(diǎn)幫助 ui->pushButton->setFlat(true); 40、設(shè)置QT窗體置頂,。 this->setWindowFlags(Qt::WindowStaysOnTopHint); 41,、判斷sqlite數(shù)據(jù)表是否存在。 QStringList existTables; existTables=dataBase->tables(); if(!existTables.contains(userId)) QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE"); //創(chuàng)建不帶名稱的數(shù)據(jù)庫連接,,可以理解成ADO中的Connection Driver Class name Constructor arguments File to include QPSQL QPSQLDriver PGconn *connection qsql_psql.cpp QMYSQL QMYSQLDriver MYSQL *connection qsql_mysql.cpp QOCI QOCIDriver OCIEnv *environment, OCISvcCtx *serviceContext qsql_oci.cpp QODBC QODBCDriver SQLHANDLE environment, SQLHANDLE connection qsql_odbc.cpp QDB2 QDB2 SQLHANDLE environment, SQLHANDLE connection qsql_db2.cpp QTDS QTDSDriver LOGINREC *loginRecord, DBPROCESS *dbProcess, const QString &hostName qsql_tds.cpp QSQLITE QSQLiteDriver sqlite *connection qsql_sqlite.cpp QIBASE QIBaseDriver isc_db_handle connection qsql_ibase.cpp ODBC連接適合數(shù)據(jù)庫類型 連接方式access "Driver={microsoft access driver(*.mdb)};dbq=*.mdb;uid=admin;pwd=pass;"dBase "Driver={microsoft dbase driver(*.dbf)};driverid=277;dbq=------------;"oracle "Driver={microsoft odbc for oracle};server=oraclesever.world;uid=admin;pwd=pass;"MSSQL server "Driver={sql server};server=servername;database=dbname;uid=sa;pwd=pass;"MS text "Driver={microsoft text driver(*.txt; *.csv)};dbq=-----;extensions=asc,csv,tab,txt;Persist SecurityInfo=false;"Visual Foxpro "Driver={microsoft Visual Foxpro driver};sourcetype=DBC;sourceDB=*.dbc;Exclusive=No;"MySQL "Driver={mysql};database=yourdatabase;uid=username;pwd=yourpassword;option=16386;"SQLite "Driver={SQLite3 ODBC Driver};Database=D:\SQLite\*.db"PostgreSQL "Driver={PostgreSQL ANSI};server=127.0.0.1;uid=admin;pwd=pass;database=databaseName"OLEDB連接適 合的數(shù)據(jù)庫類型 連接方式access "Provider=microsoft.jet.oledb.4.0;data source=your_database_path;user id=admin;password=pass;"oracle "Provider=OraOLEDB.Oracle;data source=dbname;user id=admin;password=pass;"MS SQL Server "Provider=SQLOLEDB;data source=machinename;initial catalog=dbname;userid=sa;password=pass;"MS text "Provider=microsof.jet.oledb.4.0;data source=your_path;Extended Properties'text;FMT=Delimited' //參見QSqlDatabase的文檔http://doc./4.0/qsqldatabase.html#addDatabase db.setDatabaseName("UserDB"); if ( !db.open()) { QMessageBox::critical(NULL, QObject::tr("Collection"), QObject::tr("數(shù)據(jù)庫連接失?。?)); return ; } if(db.tables().isEmpty()) { QMessageBox::critical(NULL, QObject::tr("Collection"), QObject::tr("數(shù)據(jù)庫連接失??!")); } 42、QString 轉(zhuǎn)換 unsigned char* ,。 QString str = "ABCD"; int length = str.length(); unsigned char *sequence = NULL; sequence = (unsigned char*)qstrdup(str.toAscii().constData()); 43,、怎樣獲取手機(jī)串號(hào)? TPlpVariantMachineId machineId; PlpVariant::GetMachineIdL(machineId); 44,、自定義按鍵事件與控件大小變化事件 //按鍵事件 virtual void keyPressEvent(QKeyEvent *k); //控件改變重繪事件 virtual void paintEvent(QPaintEvent *); 45,、獲取QTableView行信息內(nèi)容 QSqlQueryModel model;//以綁定數(shù)據(jù)內(nèi)容的QSqlQueryModel query.prepare("delete from glossary where [work]=:work and [explain]=:explain"); QModelIndex index = ui->tableView->currentIndex(); query.bindValue(":work", model->record(index.row()).value(0).toString()); query.bindValue(":explain", model->record(index.row()).value(1).toString());
|