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实现表格样式自定义显示结构。
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;irowCount();i++)
{
QString s;
s=model->record(i).value(“EmployeeID”).toString();
QPushButton *LineEdit1=new QPushButton(s);//绑定在表格中的控件类型
insertRow(i);
setCellWidget(i,0,LineEdit1);
}
db.close();
17、实现不规则窗体显示。
//自定义不规则窗体
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);
18、重写鼠标控制窗体移动事件
//声明的对象
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();
}
}
19、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<
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
#include
#include
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”)
1、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);
2、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”) 1、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); 2、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会保持这个连接,直到通信的结束。
21、Qt窗体布局操作
布局中主要的操作有
水平布局, 垂直布局, 打破布局。
当只有一个控件时,不能进行布局操作。布局操作是多个控件,或者对话框的操纵。
选择多个窗体控件,按住shift键,鼠标点击选取,右键进行布局操纵。
当选中对话框主窗体时,可以进行窗体上控件的布局操作。
该操纵将对窗体上的控件或者布局进行,水平布局或者垂直布局操纵
22、Qt绘图模式
Qt助手,放大缩小,很方便。
绘图系统
主要基于三个类,QPainter, QPaintDevice, QPaintEngine.
QPainter用于执行绘图操作。QPaintDevice使用QPaint进行绘图所使用的二维空间。QPaintEngine提供了在不同设备上的绘图接口,被QPainter, QPaintDevice内部使用,对于程序员来说是隐藏的,只有在创建自己的设备类型时,才能用到。
QPainter能用画笔作图,画文字或者图形。
画 填充 创建设备 读写图形文件 样式
QPaintDevice是用于画图的设备的基类。
QPaintDevice的子类有 QWidget, QImage, QPixmap, QGLWidget, QGLPixelBuffer, QPicture and QPrinter。
23、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){//其它相关处理}
24、一个工程中出现多个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;
}
}
25、资源文件的动态加载
在构造函数中添加如下:
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);
26、如何对LineEdit输入数据进行格式限制。
QLineEdit 中对输入字符输入格式的控制通过inputMask与validators实现。
使用时,详细阅读2个的说明。
QIntValidator *vv=new QIntValidator(this);
ui.lineEdit->setValidator (vv);
27、二维图形框架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维图元的管理与交互提供了一个框架,可以实现这些图元的可视化,并支持缩放和旋转。
28、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)
29、要想界面一直存在用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();
}