1.程序能夠顯示中文
#include <QTextCodec>
QTextCodec::setCodecForTr(QTextCodec::codecForLocale());html
2.鏈接數據庫//http://www.im80hou.com/html/mysql/2009/1003/1538.html
.pro中添加:QT += sqlnode
#include "QtSql/qsqldatabase.h"
#include <qsqlquery.h>
#define DB_SALES_DRIVER "QPSQL7"
#define DB_SALES_DBNAME "db"
#define DB_SALES_USER "user"
#define DB_SALES_PASSWD "pwd"
#define DB_SALES_HOST ""
QSqlDatabase db = QSqlDatabase::addDatabase ( DB_SALES_DRIVER);
db.setDatabaseName( DB_SALES_DBNAME );
db.setUserName( DB_SALES_USER );
db.setPassword( DB_SALES_PASSWD );
db.setHostName( DB_SALES_HOST );
if ( db.open() ) {
// 數據庫被成功打開,咱們如今能夠運行SQL命令
cout<<"鏈接數據庫成功"<<endl;
}
else cout<<"鏈接數據庫失敗"<<endl;
sql語句:
QSqlQuery query;
query.exec("select short_name from merchants_def");
while(query.next())
{
QString name = query.value(1).toString();
printf ("name = %s\n", name.toUtf8().data());//toUtf8(), toAscii(), fromUtf8()
num++;
}mysql
//動態
int a1234=10;
query.prepare("select * from merchants_def where merchant_no=:a1234");
query.bindValue(":a1234", a1234);
query.exec();
while(query.next()){
int x=query.value(0).toInt();
cout<<"x="<<x<<endl;
}
3.treewidget
QTreeWidgetItem *issuer1 = new QTreeWidgetItem(m_ui->treeWidget);
issuer1->setText(0, tr("髮卡方1"));
QTreeWidgetItem *merchant1 = new QTreeWidgetItem(issuer1);
merchant1->setText(0, tr("商戶1"));
merchant1->setText(1, tr("Yes"));linux
QTreeWidgetItem *outlet1 = new QTreeWidgetItem(merchant1);
outlet1->setText(0, tr("網點1"));
outlet1->setText(1, tr("Yes"));程序員
QTreeWidgetItem *outlet2 = new QTreeWidgetItem(merchant1);
outlet2->setText(0, tr("網點2"));
outlet2->setText(1, tr("Yes"));算法
QTreeWidgetItem *merchant2 = new QTreeWidgetItem(issuer1);
merchant2->setText(0, tr("商戶2"));
merchant2->setText(1, tr("Yes"));
4.tablewidget(每次修改後從新顯示錶)
#include <qtabwidget.h>
顯示table:
m_ui->tableWidget_2->setRowCount(2);
m_ui->tableWidget_2->setItem(0,1,new QTableWidgetItem(tr("123")));
m_ui->tableWidget_2->setItem(1,1,new QTableWidgetItem(tr("12")));
取某值:
g_select_key[j]=atoi(m_ui->tableWidget->item(temp[j],0)->text().toAscii().data());
選中行:
QItemSelectionModel *m = m_ui->tableWidget_2->selectionModel();
QModelIndexList indexes = m->selectedIndexes();
QModelIndex index;sql
int temp[11]={0};
int which_row[11]={0};
int i=0;
int count_no = 10;
foreach(index,indexes){數據庫
temp[i++]= index.row();
}
if(i==0)
QMessageBox::warning(this,tr("警告"),tr("請先選中一行"));
else
if(i==1)
{
which_row[0]=temp[0];
if(which_row[0]>=count_no)
QMessageBox::warning(this,tr("警告"),tr("選擇有誤"));
else
{編程
cout<<"修改。。。"<<endl;
cout<<"which_row[0]="<<which_row[0]<<endl;//修改以後更新表
m_ui->tableWidget_2->setRowCount(3);
m_ui->tableWidget_2->setItem(0,1,new QTableWidgetItem(tr("123")));
m_ui->tableWidget_2->setItem(1,1,new QTableWidgetItem(tr("12")));
m_ui->tableWidget_2->setItem(2,1,new QTableWidgetItem(tr("12")));
}
}
else
if(i>1)
{
int j;
for(j=1;j<i;j++)
{
if(temp[j]==temp[0])
break;
}
if(j==1)
{
which_row[0]=temp[0];
if(which_row[0]>=count_no)
QMessageBox::warning(this,tr("警告"),tr("選擇有誤"));
else
{
cout<<"修改。。。"<<endl;
cout<<"which_row[0]="<<which_row[0]<<endl;//修改以後更新表
m_ui->tableWidget_2->setRowCount(3);
m_ui->tableWidget_2->setItem(0,1,new QTableWidgetItem(tr("123")));
m_ui->tableWidget_2->setItem(1,1,new QTableWidgetItem(tr("12")));
m_ui->tableWidget_2->setItem(2,1,new QTableWidgetItem(tr("12")));
}
}
else
QMessageBox::warning(this,tr("警告"),tr("一次只能修改一行"));
}windows
else
return;
5.comboBox
#include <qcombobox.h>
for( i=0; i<num; i++)
ui->merchant_comboBox->addItem(QString::fromUtf8(short_name[i]));
merchant_name=ui->merchant_comboBox->currentText();//comboBox
start_date=ui->start_dateEdit->text();//dateEdit
end_date=ui->end_dateEdit->text();
report_type=ui->type_comboBox->currentText();
s=ui->merchants_comboBox->itemText(i);//
6.登陸框(http://hi.baidu.com/yafeilinux/blog/item/a335cd10a465d174cb80c42d.html)
QApplication a(argc, argv);
Widget w;
loginDlg login;
if(login.exec()==QDialog::Accepted)
{
w.show();
return a.exec();
}
else return 0;
//
if(m_ui->usrlineEdit->text()==tr("hqq")&&m_ui->pwdlineEdit->text()==tr("hqq"))
//判斷用戶名和密碼是否正確
accept();
else{
QMessageBox::warning(this,tr("Warning"),tr("user name or password error!"),QMessageBox::Yes);
//若是不正確,彈出警告對話框
m_ui->usrlineEdit->clear();//清空用戶名輸入框
m_ui->pwdlineEdit->clear();//清空密碼輸入框
m_ui->usrlineEdit->setFocus();//將光標轉到用戶名輸入框
}
7.橫向滾動條和spinBox關聯使用
ui->spinBox->setRange(0, 130);//設置各自的取值範圍
ui->horizontalSlider->setRange(0, 130);
//滑塊和Spin組件的值的變化都會對應的改變
QObject::connect(ui->spinBox, SIGNAL(valueChanged(int)),
ui->horizontalSlider, SLOT(setValue(int)));
QObject::connect(ui->horizontalSlider, SIGNAL(valueChanged(int)),
ui->spinBox, SLOT(setValue(int)));
ui->spinBox->setValue(35);//注意這裏的設置也會影響slider
8.progressbar的使用(點擊按鈕觸發progressbar,而不是觸發整個界面)
for (i=1;i<=100;i++)
{
m_ui->progressbar->setValue(i);
for ( j=0; j<1000*1000*4;j++)
{
}
}
9.mdi:在Qt中要製做MDI介面的視窗,是使用QMainWindow ,並將其中心元件(Central Widget)設爲QMdiArea實例,而每個MDI子視窗,則使用QMdiArea的addSubWindow()來加入。
#include <QtGui>
在on_actionNew_N_triggered()中:
QMdiArea *mdiArea = new QMdiArea;
this->setCentralWidget(mdiArea);
QTextEdit *textEdit = new QTextEdit;
textEdit->setWindowTitle("File1");
mdiArea->addSubWindow(textEdit);
10.connect(sender, signal, receiver, member)
sender是發生器,signal是發出的信號,receiver是接收器,member是槽。
如:connect(hostLineEdit, SIGNAL(textChanged(const QString &)),
this, SLOT(enableGetFortuneButton()));
11.設置可編輯狀態
for(j=0;j<count;j++)
m_ui->tableWidget->item(i,19)->setFlags(Qt::ItemIsEditable);
12.QMessageBox
if(QMessageBox::information(this,tr("警告"),tr("肯定刪除?"),QMessageBox::No,QMessageBox::Yes)==16384)
13.QFile
QFile file("/home/hqq/1.txt");
char *msg="1234";
file.open( QIODevice::WriteOnly);
file.write(msg, qstrlen(msg));
file.close();
14.execl
QString fileName=QFileDialog::getSaveFileName(this,tr("Save File"),"",tr("file(*.CSV)"));
cout<<"fileName="<<fileName.toAscii().data()<<endl;
if(fileName == "")
return;
QTextCodec *code;
code = QTextCodec::codecForName("gb18030");
std::string strbuffer = code->fromUnicode(fileName).data();
FILE *fileWrite = fopen( strbuffer.c_str(),"w+");
QString strFemale = "Female ";
QString strMale = "Male ";
QString strPatientCount = "Patient ";
char a[20]="abc";
char b[20]="一二三";
QString str ="\n";
//std::string strCountbuffer = code->fromUnicode(strFemale+","+strMale+","+strPatientCount+str+QString().setNum(femaleCount)+","+QString().setNum(maleCount)+","+QString().setNum(patientCount)).data();
//std::string strCountbuffer=code->fromUnicode(strFemale+","+strMale+","+strPatientCount+str+QString().setNum(1)+","+QString().setNum(1)+","+QString().setNum(1)).data();
//std::string strCountbuffer=code->fromUnicode(strFemale+strMale+strPatientCount+str+QString().setNum(1)).data();//可用
std::string strCountbuffer=code->fromUnicode(strFemale+strMale+strPatientCount+str+a+' '+tr(b)).data();
QFile file;
file.open(fileWrite, QIODevice::WriteOnly);
file.write(strCountbuffer.c_str(), qstrlen(strCountbuffer.c_str()));
file.close();
15.打印
#include <QPrinter>
#include <QPainter>
#include <QFileDialog>
#include <QPrintDialog>
#include <QTextDocument>
QTextDocument *document = ui->textEdit->document();
QPrinter printer;
QPrintDialog dlg(&printer, this);
dlg.setWindowTitle(tr("打印文檔"));
if (dlg.exec() != QDialog::Accepted)
return;
document->print(&printer);
一、QGridLayout
QGridLayout包含多個grid,它並無要求其中的每一個grid的size相同,一般狀況下,每一個grid的size是不一樣的。
對於成員函數addWidget(widget, fromRow, fromColumn, rowSpan, columnSpan, alignment):rowSpan表示新添加進來的widget在垂直方向上跨越或者佔據多少個grid。
columnSpan表示新添加進來的widget在水平方向上跨越或者佔據多少個grid。
二、line edit的input mask
對一個line edit設置了input mask屬性後,也就限定了輸入字符。通常狀況下,須要填寫的字符位置是空白的,可是,你可讓該空白以某個字符佔位,你只需在指定input mask的字符末尾添加「*?」便可,把‘?’換爲你想用來佔位的一個字符。
三、利用designer設計ui
整體上來講,先建立各個控件,而後設置layout相對來講好些。另外,grid layout對設置佈局前的窗口布局依賴比較大,即若是設置grid layout前的佈局不一樣,則生效後的差異可能較大。
四、QLabel的buddy屬性
在qt中,只有QLabel實現了buddy機制。
只有你爲QLabel設置了buddy後,文本中的字符‘&’才能如下劃線顯示(這點與其餘widget不一樣),並建立了對應的快捷鍵(固然,須要+Alt),而後能夠利用快捷鍵迅速的把光標定位到該QLabel的buddy中,例如:
QLabel *what = new QLabel(「Find &What:」);
該實例對應快捷鍵Alt+w。
五、QMouseEvent中的座標
QMouseEvent中保存了兩個座標,一個是全局座標,固然另一個是局部座標。
全局座標(globalPos())便是桌面屏幕座標(screen coordinates),這個跟windows下的調用getCursorPos函數獲得的結果一致。
局部座標(pos())便是相對當前active widget的座標,左上角座標爲(0, 0)。
補充一個公式:
this->mapFromGlobal(this->cursor().pos()) = event.pos()
六、鼠標跟蹤
在qt中,鼠標跟蹤對應函數mouseMoveEvent。可是,默認狀況下他並不能如期象你想象的那樣響應鼠標的移動。此時,你只需在合適的位置調用一下函數setMouseTracking(true)便可。
默認狀況下,mouseMoveEvent響應你按下鼠標的某個鍵(拖動,但不侷限於左鍵拖動)的鼠標移動。
七、鼠標左鍵拖動和左鍵點擊的判斷
鼠標左鍵點擊很容易判斷,通常就是在重寫mousePressEvent函數,示例以下:
void XXXWidget::mousePressEvent(QMouseEvent *event)
{
if(event->button() == Qt:leftButton)
{
// todo …
}
}
左鍵拖動的判斷通常放在mouseMoveEvent函數中,可是你不能向上例同樣來判斷,由於該函數的event參數老是返回Qt::NoButton。你能夠這樣作:
void XXXWidget::mouseMoveEvent(QMouseEvent *event)
{
if(event->buttons() & Qt:leftButton)
{
// todo …
}
}
八、窗口有一個子窗口,子窗口隨着父窗口最小化而最小化的實現:
child = new QWidget(parent);
child->setWindowFlags(Qt::Window);
可是,若是父子窗口都顯示的話,此時銷燬父窗口,子窗口依然顯示;而後關閉子窗口,纔算徹底關閉了整個窗口。理想的作法是這樣的:
child = new QWidget(parent);
child->setWindowFlags(Qt::Window | Qt::SubWindow);
九、解決中文亂碼問題
//解決中文亂碼問題
QTextCodec::setCodecForTr(QTextCodec::codecForName(「GB2312″));
QTextCodec::setCodecForLocale(QTextCodec::codecForName(「GB2312″));
QTextCodec::setCodecForCStrings(QTextCodec::codecForName(「GB2312″));
十、實現多窗體切換。
信號通信方法(參數1事件響應對象,參數2響應事件,參數3本實例對象指針,參數4響應方法)
connect(this->ui->butSumbie, SIGNAL(clicked()), this, SIGNAL(send1()));
信號通信方法(參數1事件響應對象,參數2響應事件,參數3本實例對象指針,本實例對象執行方法)
connect(this->ui->butSumbie, SIGNAL(clicked()), this, SLOT(close()));
事件中調用說明:
信號通信方法(參數1事件響應對象,參數2響應事件,參數3本實例對象指針,參數4響應方法)
MyWidget w;
執行權限交給主窗體
app.setMainWidget(&w);
十一、獲取當前執行程序路徑:QCoreApplication::applicationDirPath()
十二、獲取當前執行程序文件夾下所有文件內容而且保存到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);
}
1三、文件讀取實現內容實現代碼。
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();
}
1四、文件寫入實現代碼段
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();//執行寫入
file.close();
}
1五、數據庫QSqlQueryModel類使用意見SqlServer數據庫鏈接。
ui->setupUi(this);
db = QSqlDatabase::addDatabase(「QODBC」);//定義數據庫鏈接類型。db對象在執行QSqlQueryModel綁定中一直必須是開啓狀態而且要可見不然無數據內容顯示。
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);//能夠執行查詢與刪除修改添加操做對象。
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();
1六、例用QTableWidget實現表格樣式自定義顯示結構。
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);//設置字段名
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();
1七、實現不規則窗體顯示。
//自定義不規則窗體
QPalette p = palette();
QPixmap img(「a.jpg」);
//窗體掩碼圖定義
//QBitmap mask(「mask.png」);
p.setBrush(QPalette::Window, QBrush(img));
setPalette(p);
//設置掩模圖
//setMask(mask);
setWindowFlags(Qt::FramelessWindowHint);
resize(800, 600);
//ui->setupUi(this);
1八、重寫鼠標控制窗體移動事件
//聲明的對象
QPoint last,pos0;//鼠標移動控制對象
//重寫的鼠標移動事件
void MainWindow::mouseMoveEvent(QMouseEvent *e)
{
if(e->buttons() & Qt::LeftButton)
{
//QMessageBox::about(this,」進入移動」,」成功進入移動事件」);
QPoint newpos = e->globalPos();
QPoint upleft = pos0 + newpos – last;
move(upleft);
}
}
//重寫的鼠標按下事件
void MainWindow::mousePressEvent(QMouseEvent *e)
{
if(e->button()==Qt::LeftButton)
{
//QMessageBox::about(this,」進入按下」,」成功進入按下事件」);
last = e->globalPos();
pos0 = e->globalPos() – e->pos();
}
}
1九、QT中調用DLL實現代碼段
這個推薦一款小工具 viewdll.exe 。實例代碼和工具下面提供下載。將DLL文件直接拖過去,就直接顯示DLL裏的函數名。固然也不是全部DLL都能顯示。
用QT生成DLL,直接導出函數的方法。
用QTcreator dll嚮導創建工程。把全部.H文件刪除,在惟一的.CPP文件中編寫你所要導出的函數,函數模版
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是函數名
if (myFunction)
myFunction();//調用的classdll,也就是你的函數生成dll的文件:
//mydll.h
extern 「C」 __declspec(dllexport) int maxfun(int,int); //函數
struct __declspec(dllexport) nNode //結構體
{
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}; //這裏一個結構體對象
///下面是程序調用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中的網絡編程與實現。QT中共提供四個與套按字相關的類,分別是:
QServerSocket:TCP-based server
QSocket: Buffered TCP connection
QSocketDevice: Platform-independent low-level socket API
QSocketNotifier: Support for socket callbacks
下面介紹使用QT進行網絡編程,咱們使用一個簡單的C/S模式網絡程序說明如何使用QT中的套接字。同時咱們用TCP和UDP兩種協議實現這個程序(該程序客戶端與服務端各向對方發送一個字符口串「abc」)
一、UDP實現
UDP是不鏈接協議,沒有客戶端與服務端的概念。
1)創建套接字相關對象
QSocketDevice *MUReceiveSocket; //套接字對象
QSocketNotifier *MSocketNotifier; //套接字監聽對象
2)初始化套接字相關對象
MUReceiveSocket=new QSocketDevice(QSocketDevice::Datagram);
//UDP初始化
QHostAddress MyAddress;
QString FakeAddress;
FakeAddress = get_eth1_ip(); //取得接口IP
MyAddress.setAddress(FakeAddress);
MUReceiveSocket->bind(MyAddress,Port);
//綁定到指定網絡接口地址(IP),指定邏輯端口
MSocketNotifier = new QSocketNotifier(MUReceiveSocket->socket(),QSocketNotifier::Read,0,」MSocketNotifier」);
//監聽MUReceiveSocket套接字
3)定義用實現響應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)關聯套接字的signal和接收slot
connect(MSocketNotifier,SIGNAL(activated(int)),this,SLOT(OnMReceive()));
//當MSocketNotifier檢測到MUReceiveSocket活躍時調用OnMReceive
5)發送字符串
char information[20];
strcpy(information,「abc「);
MUReceiveSocket->writeBlock(information,length,MyAddress,2201);
二、TCP實現
TCP的實現與UDP的實現大同小異,它是面象鏈接的協議。這裏只介紹與UDP不一樣的地方。
服務端:
1)套接字對象的定義
比UDP多定義一個套接字,一個用來監聽端口,一個用來通訊。
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表明所容許的最大鏈接數
ClienttNotifier = new QSocketNotifier(ClientSocket->socket(),QSocketNotifier::Read,0,」ClientSocket」);
ServerNotifier = new QSocketNotifier(ServerSocket->socket(),QSocketNotifier::Read,0,」ServerSocket」);
3)響應鏈接(在定義slot中響應)
當收到客戶端的鏈接後,響應它,並以ClientSocket接收:
ServerSocket->SetSocket(ClientSocket->socket());
4)接收信息slot與UDP一致,這裏不在敘述。
客戶端實現:
客戶端的實現與UDP實現大同小異,不一樣的地方只是客戶端套接字不須要bind端口,由於鏈接上服 務端後TCP會保持這個鏈接,直到通訊的結束。
操做系統:ARM-LINUX QT版本:QT-2.3.2-FOR-LINUX GUI:Qtopia 在LINUX下進行網絡編程,咱們可使用LINUX提供的統一的套接字接口。可是這種方法牽涉到太多的結構體,好比IP地址,端口轉換等,不熟練的人每每容易犯這樣那樣的錯誤。QT中提供的SOCKET徹底使用了類的封裝機制,使用戶不須要接觸底層的各類結構體操做。並且它採用QT自己的signal-slot機制,使編寫的程序更容易理解。 QT中共提供四個與套按字相關的類,分別是: QServerSocket:TCP-based server QSocket: Buffered TCP connection QSocketDevice: Platform-independent low-level socket API QSocketNotifier: Support for socket callbacks 下面介紹使用QT進行網絡編程,咱們使用一個簡單的C/S模式網絡程序說明如何使用QT中的套接字。同時咱們用TCP和UDP兩種協議實現這個程序(該程序客戶端與服務端各向對方發送一個字符口串「abc」) 一、UDP實現 UDP是不鏈接協議,沒有客戶端與服務端的概念。 1)創建套接字相關對象 QSocketDevice *MUReceiveSocket; //套接字對象 QSocketNotifier *MSocketNotifier; //套接字監聽對象 2)初始化套接字相關對象 MUReceiveSocket=new QSocketDevice(QSocketDevice::Datagram); //UDP初始化 QHostAddress MyAddress; QString FakeAddress; FakeAddress = get_eth1_ip(); //取得接口IP MyAddress.setAddress(FakeAddress); MUReceiveSocket->bind(MyAddress,Port); //綁定到指定網絡接口地址(IP),指定邏輯端口 MSocketNotifier = new QSocketNotifier(MUReceiveSocket->socket(),QSocketNotifier::Read,0,」MSocketNotifier」); //監聽MUReceiveSocket套接字 3)定義用實現響應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)關聯套接字的signal和接收slot connect(MSocketNotifier,SIGNAL(activated(int)),this,SLOT(OnMReceive())); //當MSocketNotifier檢測到MUReceiveSocket活躍時調用OnMReceive 5)發送字符串 char information[20]; strcpy(information,「abc「); MUReceiveSocket->writeBlock(information,length,MyAddress,2201); 二、TCP實現 TCP的實現與UDP的實現大同小異,它是面象鏈接的協議。這裏只介紹與UDP不一樣的地方。 服務端: 1)套接字對象的定義 比UDP多定義一個套接字,一個用來監聽端口,一個用來通訊。 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表明所容許的最大鏈接數 ClienttNotifier = new QSocketNotifier(ClientSocket->socket(),QSocketNotifier::Read,0,」ClientSocket」); ServerNotifier = new QSocketNotifier(ServerSocket->socket(),QSocketNotifier::Read,0,」ServerSocket」); 3)響應鏈接(在定義slot中響應) 當收到客戶端的鏈接後,響應它,並以ClientSocket接收: ServerSocket->SetSocket(ClientSocket->socket()); 4)接收信息slot與UDP一致,這裏不在敘述。 客戶端實現: 客戶端的實現與UDP實現大同小異,不一樣的地方只是客戶端套接字不須要bind端口,由於鏈接上服 務端後TCP會保持這個鏈接,直到通訊的結束。
2一、Qt窗體佈局操做
佈局中主要的操做有
水平佈局, 垂直佈局, 打破布局。
當只有一個控件時,不能進行佈局操做。佈局操做是多個控件,或者對話框的操縱。
選擇多個窗體控件,按住shift鍵,鼠標點擊選取,右鍵進行佈局操縱。
當選中對話框主窗體時,能夠進行窗體上控件的佈局操做。
該操縱將對窗體上的控件或者佈局進行,水平佈局或者垂直佈局操縱
2二、Qt繪圖模式
Qt助手,放大縮小,很方便。
繪圖系統
主要基於三個類,QPainter, QPaintDevice, QPaintEngine.
QPainter用於執行繪圖操做。QPaintDevice使用QPaint進行繪圖所使用的二維空間。QPaintEngine提供了在不一樣設備上的繪圖接口,被QPainter, QPaintDevice內部使用,對於程序員來講是隱藏的,只有在建立本身的設備類型時,才能用到。
QPainter能用畫筆做圖,畫文字或者圖形。
畫 填充 建立設備 讀寫圖形文件 樣式
QPaintDevice是用於畫圖的設備的基類。
QPaintDevice的子類有 QWidget, QImage, QPixmap, QGLWidget, QGLPixelBuffer, QPicture and QPrinter。
2三、CListWidget與CTableWidget編程注意事項
在執行CListWidget與CTableWidget等相似的列表控件的Clear操做時,系統常常崩潰,緣由分析。這個clear操做由於改變了列表的內容,會觸發其它的信號。特別是下面的兩個函數。
CListWidget的函數
void currentItemChanged ( QListWidgetItem * current, QListWidgetItem * previous )
void currentRowChanged ( int currentRow )
CTableWidget的函數。
void currentCellChanged ( int currentRow, int currentColumn, int previousRow, int previousColumn )
void currentItemChanged ( QTableWidgetItem * current, QTableWidgetItem * previous )
若是,在下面的函數中,沒有加入信號參數檢測,就很容易出錯。主要檢查currentRow 是否大於或者等於0。current,previous 是否有效。若是不檢查,並根據該參數,調用了其它的方法。當currentRow =-1; 時,就會發生錯誤。
ui.tableWidget->item(row, 0); row=-1時,調用就會產生錯誤。
ui.listWidget->item(row); row=-1時,調用就會產生錯誤。
錯誤解決方法:加入錯誤檢查,
if (row>=0){//其它相關處理}
2四、一個工程中出現多個QMainWindow並同時顯示的方案。
問題描述:
在一個CMainWindow CMyWin1的繼承類中,若是再使用一個CMainWindow類CMyWin2;
在CMyWin1中使用如下代碼、
CMyWin2 mw;
mw.show ()
mw 一閃就沒有了。具體緣由不明。
定義窗體局部變量: CDataManager *m_pDataMager;
調用過程以下,並創建信號鏈接,監控信號 destryed,接收道該信號時,作一個槽處理。
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);
}
在函數after_DataManage_Destoryed中,進行窗體的delete,並設置變量爲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;
}
}
2五、資源文件的動態加載
在構造函數中添加以下:
QIcon icon;
icon.addPixmap(QPixmap(QString::fromUtf8(「../resource/well.png」)), QIcon::Normal,QIcon::Off);
ui.actionLoad->setIcon(icon);
tableWidget設置高度寬帶
ui.tableWidget->setColumnWidth(0,280);
ui.tableWidget->setColumnWidth(1,280);
for (int i=0;i<10;i++)
ui.tableWidget->setRowHeight(i,20);
2六、如何對LineEdit輸入數據進行格式限制。
QLineEdit 中對輸入字符輸入格式的控制經過inputMask與validators實現。
使用時,詳細閱讀2個的說明。
QIntValidator *vv=new QIntValidator(this);
ui.lineEdit->setValidator (vv);
2七、二維圖形框架Graphics View
Graphics View框架實現了模型-視圖結構的圖形管理,能對大量的圖元進行管理,支持碰撞檢測、座標變換和圖元組等多種方便的操做。Graphics View支持事件傳播體系結構,可使圖元在場景(scene)中獲得提升了一倍的精確交互能力。圖元可以處理鍵盤事件,鼠標按下、移動、釋放和雙擊事件,也能跟蹤鼠標的移動。在Graphics View框架中,經過BSP(二元空間劃分樹,Binary Space Partionng)來提供快速的圖元查找,這樣就能實時地顯示大場景,甚至上百萬個圖元。
Graphics View框架提供基於圖元的模型-視圖編程,相似於Qt InterView的模型-視圖結構,只是這裏的數據是圖形。Graphics View框架中包括三個主要的類:QGraphicsItem, QGraphicsScene 和 QGraphicsView。
Graphics View爲大量定製的2維圖元的管理與交互提供了一個框架,能夠實現這些圖元的可視化,並支持縮放和旋轉。
2八、Graphics View框架繼續學習
主要內容:場景 QGraphicsScene 視圖 QGraphicsView 圖元 QGraphicsItem
示例:Examples and Demos >> Graphics View
QGraphicsScene是QGraphicsItems的容器。它與QGraphicsView一塊兒實現了圖元的可視化,例如線,矩形,文本,以及定製的圖元。QGraphicsScene也提供瞭如下功能,讓你高效的肯定圖元的位置以及圖元的可視性。
QGraphicsScene scene;
scene.addText(「Hello, world!」);
QGraphicsView view(&scene);
view.show();
重點示例程序:
Diagram Scene
//圖元的外接矩形區域(虛函數的實現)
QRectF CGeoObjCnoline::boundingRect() const
//圖元的繪製路徑(虛函數的實現)
QPainterPath CGeoObjCnoline::shape() const
//圖元的繪製(虛函數的實現)
void CGeoObjCnoline::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
2九、要想界面一直存在用new建立
用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();
}
指針用局部變量,使用的時候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();
}
1: 使用QTableView本身帶的函數,函數原型以下:
ui.tableWidget->resizeColumnToContents (0);
將第一列根據內容自動調整列寬。
根據內容自動調整某列的列寬
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.
根據內容自動調整全部列的列寬
void QTableView::resizeColumnsToContents () [slot]
Resizes all columns based on the size hints of the delegate used to render each item in the columns.
根據內容自動調整某一行的行高
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.
根據內容自動調整全部行的行高。
void QTableView::resizeRowsToContents () [slot]
Resizes all rows based on the size hints of the delegate used to render each item in the rows.
3一、QGraphicsItem中的碰撞檢測描述
QGraphicsItem是圖元基類。QGraphics View框架提供了幾種標準的圖元,如矩形(QGraphicsRectItem、橢圓(QGraphicsEllipseItem)和文本圖元(QGraphicsTextItem)等。用戶能夠繼承QgraphicItem實現符合本身須要的圖元。
QGraphicsItem具備如下功能:
處理鼠標按下、移動、釋放、雙擊、懸停、滾輪和右鍵菜單事件
處理鍵盤輸入事件
處理拖放事件
分組
碰撞檢測
圖元有本身的座標系統,也提供場景和圖元、圖元與圖元之間的座標轉換函數。圖元能夠包含子圖元。
要建立本身的圖元,必須首先建立QGrahicsItem的一個子類,而後開始實現他的2個純虛函數。一個是boundingRect(),用於返回圖元繪製所須要的估測區域。另外一個是paint,它實現實際的繪圖操縱。舉例:
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函數有幾個目的。QGraphicsScene的圖元索引就是創建在boundingRect的基礎上。QGraphicsView也使用這個函數來從視圖上將不可見的圖元移去,以及在繪製重疊的圖元時決定須要從新組織的區域。另外,QGraphicsItem的碰撞檢測機制(collision detection)使用boundingRest來提升高效的處理。更好的碰撞檢測算法是基於shape函數的調用,shape函數將圖元的形狀的準確外觀以QPainterPath返回。
QGraphicsScene認爲全部圖元的boundingRect函數與shape函數都是不發生改變的,除非用戶進行通知。若是你想改變一個圖元的範圍,必需先調用prepareGeometryChange以容許QGraphicsScene進行更新。
碰撞檢測能夠經過如下兩種方式實現:
從新實現shape函數返回一個準確的圖元外觀形狀,依賴collidesWithItem函數進行缺省的碰撞檢測,若是形狀很是的複雜,該檢測將是很是耗時的。
從新實現collidesWithItem函數,爲本身的定製圖元編寫碰撞檢測算法。
對於多點成線的圖元可使用下面的方式返回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;
3二、sql中二進制文件經過QByteArray讀寫
從數據庫到文件
QSqlQuery myquery( *pDatabase);
QByteArray myba;
if(myquery.exec(sql))
{
QSqlRecord myrecord = myquery.record();
if (myquery.next()) {
myba = myquery.value(myrecord.indexOf(「Settings」)).toByteArray();//讀取二進制對象
}
}
else
{
initBoundary();
return false;
}
QFile mybfile(MapDataFilename);
if (!mybfile.open(QIODevice::WriteOnly))
{
initBoundary();
return false;
}
mybfile.write (myba);
mybfile.close();
從文件到數據庫
//將文件存入數據庫
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;
}
3三、QGraphicsView放大縮小中心屬性分析
將下面的函數註釋掉,是resize,不發生縮放。
void CBaseMapForm::resizeEvent ( QResizeEvent * event )
{
//m_view->doZoomAll();
}
QMatrix能夠直接進行文件存儲。 << >>。
3四、幫助文件的調用執行問題
幫助文件安裝製做:
取得當前可執行程序的路徑
QString strUrl=QApplication::applicationDirPath () ;
strUrl=QString(「file:///%1/help.htm」).arg (strUrl)
用客戶機的瀏覽器,打開網頁
desktopServices.openUrl(qqq);
3五、最簡單的圖形顯示控件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));
3六、取得QTableView的特定行,特定列的數據
QModelIndex index = ui.tableView->currentIndex();
if (!index.isValid())
{
QMessageBox::information (NULL,」提示」,」請先選擇一行數據。」);
return;
}
int iRow;
iRow = index.row();
QAbstractItemModel* model = ui.tableView->model();
//取得層數據庫的數據表名
index = model->index(iRow,1,QModelIndex());
QString strHorizonName;
strHorizonName = index.data().toString();
3七、qt下得到屏幕的分辨率
在Qt中提供了QDesktopWidget類,提供屏幕的有關信息.
能夠這麼做:
QDesktopWidget *d=QApplication::desktop();
int width=d->widht(); //屏幕的寬度
int height=d->height(); //屏幕的高度
或者簡寫以下:
int width=QApplication::desktop()->width();
int height=QApplication::desktop()->height();
3八、幹掉QT窗體的標題欄。。
setWindowFlags(Qt::FramelessWindowHint);
3九、設置QT按鈕爲透明。
//就是這句可以實現透明,真是意外的發現,但願對一些學習的朋友有點幫助
ui->pushButton->setFlat(true);
40、設置QT窗體置頂。
this->setWindowFlags(Qt::WindowStaysOnTopHint);
4一、判斷sqlite數據表是否存在。
QStringList existTables;
existTables=dataBase->tables();
if(!existTables.contains(userId))
QSqlDatabase db = QSqlDatabase::addDatabase(「QSQLITE」);
//建立不帶名稱的數據庫鏈接,能夠理解成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鏈接適合數據庫類型 鏈接方式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鏈接適合的數據庫類型 鏈接方式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.trolltech.com/4.0/qsqldatabase.html#addDatabase
db.setDatabaseName(「UserDB」);
if ( !db.open())
{
QMessageBox::critical(NULL, QObject::tr(「Collection」), QObject::tr(「數據庫鏈接失敗!」));
return ;
}
if(db.tables().isEmpty())
{
QMessageBox::critical(NULL, QObject::tr(「Collection」), QObject::tr(「數據庫鏈接失敗!」));
}
4二、QString 轉換 unsigned char* 。
QString str = 「ABCD」;
int length = str.length();
unsigned char *sequence = NULL;
sequence = (unsigned char*)qstrdup(str.toAscii().constData());
4三、怎樣獲取手機串號?
TPlpVariantMachineId machineId;
PlpVariant::GetMachineIdL(machineId);
4四、自定義按鍵事件與控件大小變化事件
//按鍵事件
virtual void keyPressEvent(QKeyEvent *k);
//控件改變重繪事件
virtual void paintEvent(QPaintEvent *);
4五、獲取QTableView行信息內容
QSqlQueryModel model;//以綁定數據內容的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());
http://blog.csdn.net/liang890319/article/category/810210/1