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