最近因为需要开发一个类似QQ的截屏功能,花了不少的时间,开始的时候很多也不懂,不知道如何下手,在网上找了很多的资料,现已经实现了截屏,移动截屏选区,通过拖动选区的八个控制点来改变选区的大小。
QT实现截屏的原理是,当点击截屏按钮(菜单栏上的截屏按钮)时,调用fullScreenWidget对象getFullScreenPixmap()方法,返回当前屏幕的QPixmap图片对象。在构造调用窗体的构造函数中,关联信号与槽,使其在点击“截屏”按钮发送信息给fullScreenWidget对象对应的槽函数,以便加载当前的背景图片。
connect(newAct,SIGNAL(triggered()),this,SLOT(screenshot()));
connect(this,SIGNAL(setPixmap(QPixmap)),fullWidget,SLOT(loadBackgroundPixmap(QPixmap)));
在fullScreenWidget类中,主要是根据当前截屏的状态来实时的判断如果截取屏幕。我在类中定义了shotState枚举类型,用来判断当前截屏的状态。定义了QPoint beginPoint,endPoint,moveBeginPoint,moveEndPoint;四个对象主要用来记录开始,结束的截屏坐标。移动的开始,结束坐标。根据不同的截屏状态和这4个坐标点的值来计算截屏的区域。我的表达能力不太好,先把核心代码上面来。fullScreenWidget.h头文件代码如下:
- #ifndef FULLSCREENWIDGET_H
- #define FULLSCREENWIDGET_H
- #include <QWidget>
- #include <QPixmap>
- #include <QPoint>
- #include <QtGui>
- #include <QPainter>
- #include <QBrush>
- class fullScreenWidget : public QWidget{
- Q_OBJECT
-
- public:
- fullScreenWidget(); //构造函数
- enum shotState{initShot,beginShot,finishShot,endShot,beginMoveShot,finishMoveShot,beginControl,finishControl}; //进行截屏的状态
- //移动选区中的8个控制点,按照顺时针方向从左上控制点到左中控制点分配编号为1~8
- enum controlPointEnum{moveControl0,moveControl1,moveControl2,moveControl3,moveControl4,moveControl5,moveControl6,moveControl7,moveControl8};
- QPixmap getFullScreenPixmap(); //获取全屏的Pixmap
-
- public slots:
- void loadBackgroundPixmap(const QPixmap &bgPixmap);//加载背景Pixmap槽函数
- void loadBackgroundPixmap(const QPixmap &bgPixmap, int x, int y, int width, int height); //加载背景pixmap槽函数,设置x,y,width,height
- void cancelSelectedRect(); //取消选择区域
- void savePixmap(); //保选取行为的方法
-
- signals:
- void finishPixmap(const QPixmap &finishPixmap); //完成切图后的图片,发送信号给连接者
- private:
- //选区框的8个点选取
- QRect tlRect; //左上点
- QRect trRect; //右上点
- QRect blRect; //左下点
- QRect brRect; //右下点
- QRect tcRect; //上中点
- QRect bcRect; //下中点
- QRect lcRect;//左中点
- QRect rcRect; //右中点
- QPainter painter;
- QPoint beginPoint,endPoint,moveBeginPoint,moveEndPoint;
- QRect selectedRect; //选择区域
- QPixmap loadPixmap,shotPixmap;
- shotState currentShotState; //当前的截屏状态
- controlPointEnum controlValue; //记录移动控制点的值
- QAction *savePixmapAction; //保存图片行为
- QAction *cancelAction; //取消选取行为
- QAction *quitAction; //退出选取行为
- QMenu *contextMenu; //选中区域右键菜单
- int screenwidth; //整个屏幕的宽度
- int screenheight; //整个屏幕的高度
- int screenx; //选区的X
- int screeny; //选区的Y
- int tipWidth,tipHeight,infoWidth,infoHeight; //加载初始框的宽度,高度;显示坐标信息的宽度,高度
-
- QRect getSelectedRect(); //获取选取
- QRect getRect(const QPoint &beginPoint, const QPoint &endPoint); //根据两个点获取选取坐标
- void initFullScreenWidget(); //初始化抓全屏的相关参数
- bool isInSelectedRect(const QPoint &point); //判断该点是否在选中区域
- void initSelectedMenu();//初始化右键菜单
- void drawTipsText(); //在屏幕上打印提示信息
- void drawSelectedPixmap(void); //在屏幕上画选取的屏幕
- void updateBeginEndPointValue(const QRect &rect); //当移动选取后,对beginPoint,endPoint坐标进行重新修改
- void checkMoveEndPoint(); //对移动的选区进行判断
- void draw8ControlPoint(const QRect &rect);
- void updateMouseShape(const QPoint &point); //更新鼠标的当前状态
- void updateMoveControlMouseShape(controlPointEnum controlValue);
- controlPointEnum getMoveControlState(const QPoint &point); //获取移动控制点状态
- QRect getMoveAllSelectedRect(void); //获取移动整个选中的选区
- QRect getMoveControlSelectedRect(void);//获取移动控制点的选区
- int getMinValue(int num1, int num2);//获取两个数中的最小值
- void drawXYWHInfo(void); //打印选取的x,y,h,w值信息
- //重写基类方法
- void keyPressEvent(QKeyEvent *event);
- void paintEvent(QPaintEvent *event);
- void mousePressEvent(QMouseEvent *event);
- void mouseReleaseEvent(QMouseEvent *event);
- void mouseMoveEvent(QMouseEvent *event);
- void mouseDoubleClickEvent(QMouseEvent *event);
- void contextMenuEvent(QContextMenuEvent *event);
- };
- #endif
fullScreenWidget.cpp类的实现文件如下:
- #include "fullScreenWidget.h"
- fullScreenWidget::fullScreenWidget()
- {
- setWindowState(Qt::WindowActive|Qt::WindowFullScreen);
- tipWidth = 300; //温馨提示框的宽度
- tipHeight = 100; //温馨提示框的高度
- infoWidth = 100; //坐标信息框的宽度
- infoHeight = 50; //坐标信息框的高度
- initFullScreenWidget();
- }
- void fullScreenWidget::initSelectedMenu()
- {
- savePixmapAction = new QAction(tr("保存选区"),this);
- cancelAction = new QAction(tr("重选"),this);
- quitAction = new QAction(tr("退出"),this);
- contextMenu = new QMenu(this);
- connect(savePixmapAction,SIGNAL(triggered()),this,SLOT(savePixmap()));
- connect(cancelAction,SIGNAL(triggered()),this,SLOT(cancelSelectedRect()));
- connect(quitAction,SIGNAL(triggered()),this,SLOT(hide()));
- }
- void fullScreenWidget::savePixmap()
- {
- QString fileName;
- fileName = QFileDialog::getSaveFileName(this,tr("保存图片"),QDir::currentPath(),tr("Images (*.jpg *.png *.bmp)"));
- if(fileName.isNull())
- return;
-
- shotPixmap.save(fileName);
- hide();
- }
- void fullScreenWidget::loadBackgroundPixmap(const QPixmap &bgPixmap)
- {
- int width,height;
- width = QApplication::desktop()->size().width();
- height = QApplication::desktop()->size().height();
- loadBackgroundPixmap(bgPixmap,0,0,width,height);
- }
- void fullScreenWidget::loadBackgroundPixmap(const QPixmap &bgPixmap, int x, int y, int width, int height)
- {
- loadPixmap = bgPixmap;
- screenx = x;
- screeny = y;
- screenwidth = width;
- screenheight = height;
- initFullScreenWidget();
- }
- QPixmap fullScreenWidget::getFullScreenPixmap()
- {
- initFullScreenWidget();
- QPixmap result = QPixmap();
- result = QPixmap::grabWindow(QApplication::desktop()->winId()); //抓取当前屏幕的图片
-
- return result;
- }
- void fullScreenWidget::paintEvent(QPaintEvent *event)
- {
- QColor shadowColor;
- shadowColor= QColor(0,0,0,100); //阴影颜色设置
- painter.begin(this); //进行重绘
- painter.setPen(QPen(Qt::blue,2,Qt::SolidLine,Qt::FlatCap));//设置画笔
- painter.drawPixmap(screenx,screeny,loadPixmap); //将背景图片画到窗体上
- painter.fillRect(screenx,screeny,screenwidth,screenheight,shadowColor); //画影罩效果
- switch(currentShotState){
- case initShot:
- drawTipsText();
- break;
- case beginShot:
- case finishShot:
- selectedRect = getRect(beginPoint,endPoint); //获取选区
- drawSelectedPixmap();
- break;
- case beginMoveShot:
- case finishMoveShot:
- selectedRect = getMoveAllSelectedRect(); //获取选区
- drawSelectedPixmap();
- break;
- case beginControl:
- case finishControl:
- selectedRect = getMoveControlSelectedRect();
- drawSelectedPixmap();
- break;
- default:
- break;
- }
- drawXYWHInfo(); //打印坐标信息
- painter.end(); //重绘结束
-
- if(currentShotState == finishMoveShot || currentShotState == finishControl){
- updateBeginEndPointValue(selectedRect); //当移动完选区后,更新beginPoint,endPoint;为下一次移动做准备工作
- }
- }
- void fullScreenWidget::keyPressEvent(QKeyEvent *event)
- {
- if(event->key() == Qt::Key_Escape){
- initFullScreenWidget();
- hide();
- }
- }
- void fullScreenWidget::mousePressEvent(QMouseEvent *event)
- {
- //当开始进行拖动进行选择区域时,确定开始选取的beginPoint坐标
- if(event->button() == Qt::LeftButton && currentShotState == initShot){
- currentShotState = beginShot; //设置当前状态为beginShot状态
- beginPoint = event->pos();
- }
-
- //移动选区改变选区的所在位置
- if(event->button() == Qt::LeftButton && isInSelectedRect(event->pos()) &&
- getMoveControlState(event->pos()) == moveControl0){
- currentShotState = beginMoveShot; //启用开始移动选取选项,beginMoveShot状态
- moveBeginPoint = event->pos();
- }
- //移动控制点改变选区大小
- if(event->button() == Qt::LeftButton && getMoveControlState(event->pos()) != moveControl0){
- currentShotState = beginControl; //开始移动控制点
- controlValue = getMoveControlState(event->pos());
- moveBeginPoint = event->pos();
- }
- }
- void fullScreenWidget::mouseReleaseEvent(QMouseEvent *event)
- {
- if(event->button() == Qt::LeftButton && currentShotState == beginShot){
- currentShotState = finishShot;
- endPoint = event->pos();
- update();
- }
- if(event->button() == Qt::LeftButton && currentShotState == beginMoveShot){
- currentShotState = finishMoveShot;
- moveEndPoint = event->pos();
- update();
- }
- //当前状态为beginControl状态时,设置状态为finishControl
- if(event->button() == Qt::LeftButton && currentShotState == beginControl){
- currentShotState = finishControl;
- moveEndPoint = event->pos();
- update();
- }
- }
- void fullScreenWidget::mouseMoveEvent(QMouseEvent *event)
- {
- //当拖动时,动态的更新所选择的区域
- if(currentShotState == beginShot){
- endPoint = event->pos();
- update();
- }
- //当确定选区后,对选区进行移动操作
- if(currentShotState == beginMoveShot || currentShotState == beginControl){
- moveEndPoint = event->pos();
- update();
- }
- updateMouseShape(event->pos()); //修改鼠标的形状
- setMouseTracking(true);
- }
- void fullScreenWidget::mouseDoubleClickEvent(QMouseEvent *event)
- {
- if(currentShotState == finishShot || currentShotState == finishMoveShot || currentShotState == finishControl){
- emit finishPixmap(shotPixmap); //当完成时发送finishPixmap信号
- hide();
- }
- }
- QRect fullScreenWidget::getRect(const QPoint &beginPoint, const QPoint &endPoint)
- {
- int x,y,width,height;
- width = qAbs(beginPoint.x() - endPoint.x());
- height = qAbs(beginPoint.y() - endPoint.y());
- x = beginPoint.x() < endPoint.x() ? beginPoint.x() : endPoint.x();
- y = beginPoint.y() < endPoint.y() ? beginPoint.y() : endPoint.y();
-
- return QRect(x,y,width,height);
- }
- void fullScreenWidget::initFullScreenWidget()
- {
- currentShotState = initShot;
- controlValue = moveControl0;
- beginPoint =QPoint(0,0);
- endPoint = QPoint(0,0);
- moveBeginPoint = QPoint(0,0);
- moveEndPoint = QPoint(0,0);
- tlRect = QRect(0,0,0,0); //左上点
- trRect = QRect(0,0,0,0); //上右点
- blRect = QRect(0,0,0,0); //左下点
- brRect = QRect(0,0,0,0); //右下点
- tcRect = QRect(0,0,0,0); //上中点
- bcRect = QRect(0,0,0,0); //下中点
- lcRect = QRect(0,0,0,0); //左中点
- rcRect = QRect(0,0,0,0); //右中点
- setCursor(Qt::CrossCursor);
- }
- bool fullScreenWidget::isInSelectedRect(const QPoint &point)
- {
- int x,y;
- QRect selectedRect;
- if(currentShotState == initShot || currentShotState == beginShot)
- return false;
- selectedRect = getSelectedRect();
- x = point.x();
- y = point.y();
-
- return selectedRect.contains(x,y);
- }
- void fullScreenWidget::cancelSelectedRect()
- {
- initFullScreenWidget();
- update(); //进行重绘,将选取区域去掉
- }
- void fullScreenWidget::contextMenuEvent(QContextMenuEvent *event)
- {
- initSelectedMenu();
- if(isInSelectedRect(event->pos())){
- contextMenu->addAction(savePixmapAction);
- }
- else{
- contextMenu->addAction(cancelAction);
- contextMenu->addAction(quitAction);
- }
- contextMenu->exec(event->pos());
- }
- void fullScreenWidget::drawTipsText()
- {
- int x = (screenwidth - tipWidth)/2;
- int y = (screenheight - tipHeight)/2;
- QColor color = QColor(100,100,100,200);
- QRect rect = QRect(x,y,tipWidth,tipHeight);
- QString strTipsText = QString(tr("温馨提示\n鼠标拖动进行截屏;截屏区域内右键保存;\n截屏区域外右键取消;ESC退出;"));
- painter.fillRect(rect,color);
- painter.setPen(QPen(Qt::white));//设置画笔的颜色为白色
- painter.drawText(rect,Qt::AlignCenter,strTipsText);
- }
- QRect fullScreenWidget::getSelectedRect()
- {
- if(currentShotState == beginMoveShot){
- return getMoveAllSelectedRect();
- }
- else if(currentShotState == beginControl){
- return getMoveControlSelectedRect();
- }
- else{
- return getRect(beginPoint,endPoint);
- }
- }
- void fullScreenWidget::updateBeginEndPointValue(const QRect &rect)
- {
- beginPoint = rect.topLeft();
- endPoint = rect.bottomRight();
-
- moveBeginPoint = QPoint(0,0);
- moveEndPoint = QPoint(0,0);
- }
- void fullScreenWidget::checkMoveEndPoint()
- {
- int x,y;
- QRect selectedRect = getRect(beginPoint, endPoint);
- QPoint bottomRightPoint = selectedRect.bottomRight();
- x = moveEndPoint.x() - moveBeginPoint.x();
- y = moveEndPoint.y() - moveBeginPoint.y();
- if(x + selectedRect.x() < 0){ //当移动后X坐标小于零时,则出现选区丢失,则计算出moveEndPoint的X最大坐标值,进行赋值
- moveEndPoint.setX(qAbs(selectedRect.x()-moveBeginPoint.x()));
- }
- if(y + selectedRect.y() < 0){ //当移动后Y坐标小于零时,则出现选区丢失,则计算出moveEndPoint的Y最大坐标值,进行赋值
- moveEndPoint.setY(qAbs(selectedRect.y() - moveBeginPoint.y()));
- }
- if(x + bottomRightPoint.x() > screenwidth){ //当移动选区后,出现超出整个屏幕的右面时,设置moveEndPoint的X的最大坐标
- moveEndPoint.setX(screenwidth - bottomRightPoint.x() + moveBeginPoint.x());
- }
- if(y + bottomRightPoint.y() > screenheight){ //当移动选区后,出现超出整个屏幕的下面时,设置moveEndPoint的Y的最大坐标值
- moveEndPoint.setY(screenheight - bottomRightPoint.y() + moveBeginPoint.y());
- }
- }
- void fullScreenWidget::draw8ControlPoint(const QRect &rect)
- {
- int x,y;
- QColor color= QColor(0,0,255); //画点的颜色设置
- QPoint tlPoint = rect.topLeft(); //左上点
- QPoint trPoint = rect.topRight(); //右上点
- QPoint blPoint = rect.bottomLeft(); //左下点
- QPoint brPoint = rect.bottomRight(); //右下点
-
- x = (tlPoint.x()+trPoint.x())/2;
- y = tlPoint.y();
- QPoint tcPoint = QPoint(x,y);
- x = (blPoint.x()+brPoint.x())/2;
- y = blPoint.y();
- QPoint bcPoint = QPoint(x,y);
- x = tlPoint.x();
- y = (tlPoint.y()+blPoint.y())/2;
- QPoint lcPoint = QPoint(x,y);
- x = trPoint.x();
- y = (trPoint.y()+brPoint.y())/2;
- QPoint rcPoint = QPoint(x,y);
- tlRect = QRect(tlPoint.x()-2,tlPoint.y()-2,6,6); //左上点
- trRect = QRect(trPoint.x()-2,trPoint.y()-2,6,6); //右上点
- blRect = QRect(blPoint.x()-2,blPoint.y()-2,6,6); //左下点
- brRect = QRect(brPoint.x()-2,brPoint.y()-2,6,6); //右下点
- tcRect = QRect(tcPoint.x()-2,tcPoint.y()-2,6,6); //上中点
- bcRect = QRect(bcPoint.x()-2,bcPoint.y()-2,6,6); //下中点
- lcRect = QRect(lcPoint.x()-2,lcPoint.y()-2,6,6);//左中点
- rcRect = QRect(rcPoint.x()-2,rcPoint.y()-2,6,6); //右中点
- painter.fillRect(tlRect,color);
- painter.fillRect(trRect,color);
- painter.fillRect(blRect,color);
- painter.fillRect(brRect,color);
- painter.fillRect(tcRect,color);
- painter.fillRect(bcRect,color);
- painter.fillRect(lcRect,color);
- painter.fillRect(rcRect,color);
- }
- void fullScreenWidget::updateMouseShape(const QPoint &point)
- {
- switch(currentShotState){
- case initShot:
- case beginShot:
- setCursor(Qt::CrossCursor);
- break;
- case beginMoveShot:
- setCursor(Qt::OpenHandCursor);
- break;
- case finishShot:
- case finishMoveShot:
- case finishControl:
- if(getSelectedRect().contains(point))
- setCursor(Qt::OpenHandCursor);
- else
- updateMoveControlMouseShape(getMoveControlState(point));
- break;
- case beginControl:
- updateMoveControlMouseShape(controlValue); //调用函数对移动8个控制点进行鼠标状态的改变
- break;
- default:
- setCursor(Qt::ArrowCursor);
- break;
- }
- }
- void fullScreenWidget::updateMoveControlMouseShape(controlPointEnum controlValue){
- switch(controlValue){
- case moveControl1:
- case moveControl5:
- setCursor(Qt::SizeFDiagCursor);
- break;
- case moveControl2:
- case moveControl6:
- setCursor(Qt::SizeVerCursor);
- break;
- case moveControl3:
- case moveControl7:
- setCursor(Qt::SizeBDiagCursor);
- break;
- case moveControl4:
- case moveControl8:
- setCursor(Qt::SizeHorCursor);
- break;
- default:
- setCursor(Qt::ArrowCursor);
- break;
- }
- }
- fullScreenWidget::controlPointEnum fullScreenWidget::getMoveControlState(const QPoint &point)
- {
- fullScreenWidget::controlPointEnum result = moveControl0;
- if(currentShotState == initShot || currentShotState == beginShot) {
- result = moveControl0;
- }
- else if(tlRect.contains(point)){
- result = moveControl1;
- }
- else if(tcRect.contains(point)){
- result = moveControl2;
- }
- else if(trRect.contains(point)){
- result = moveControl3;
- }
- else if(rcRect.contains(point)){
- result = moveControl4;
- }
- else if(brRect.contains(point)){
- result = moveControl5;
- }
- else if(bcRect.contains(point)){
- result = moveControl6;
- }
- else if(blRect.contains(point)){
- result = moveControl7;
- }
- else if(lcRect.contains(point)){
- result = moveControl8;
- }
- else{
- result = moveControl0;
- }
- return result;
- }
- QRect fullScreenWidget::getMoveAllSelectedRect(void)
- {
- QRect result;
- QPoint tmpBeginPoint,tmpEndPoint;
- int moveX,moveY;
- checkMoveEndPoint(); //对移动选区进行判断,当移动的选区超出边界,则停止移动
- moveX = moveEndPoint.x() - moveBeginPoint.x();
- moveY = moveEndPoint.y() - moveBeginPoint.y();
- tmpBeginPoint.setX(beginPoint.x() + moveX);
- tmpBeginPoint.setY(beginPoint.y() + moveY);
- tmpEndPoint.setX(endPoint.x() + moveX);
- tmpEndPoint.setY(endPoint.y() + moveY);
- result = getRect(tmpBeginPoint, tmpEndPoint);
- return result;
- }
- QRect fullScreenWidget::getMoveControlSelectedRect(void)
- {
- int x,y,w,h;
- QRect rect = getRect(beginPoint,endPoint);
- QRect result;
- switch(controlValue){
- case moveControl1:
- result = getRect(rect.bottomRight(),moveEndPoint);
- return result;
- break;
- case moveControl2:
- x = rect.x();
- y = getMinValue(moveEndPoint.y(),rect.bottomLeft().y());
- w = rect.width();
- h = qAbs(moveEndPoint.y() - rect.bottomRight().y());
- break;
- case moveControl3:
- result = getRect(rect.bottomLeft(),moveEndPoint);
- return result;
- break;
- case moveControl4:
- x = getMinValue(rect.x(),moveEndPoint.x());
- y = rect.y();
- w = qAbs(rect.bottomLeft().x() - moveEndPoint.x());
- h = rect.height();
- break;
- case moveControl5:
- result = getRect(rect.topLeft(),moveEndPoint);
- return result;
- break;
- case moveControl6:
- x = rect.x();
- y = getMinValue(rect.y(),moveEndPoint.y());
- w = rect.width();
- h = qAbs(moveEndPoint.y() - rect.topLeft().y());
- break;
- case moveControl7:
- result = getRect(moveEndPoint,rect.topRight());
- return result;
- break;
- case moveControl8:
- x = getMinValue(moveEndPoint.x(),rect.bottomRight().x());
- y = rect.y();
- w = qAbs(rect.bottomRight().x() - moveEndPoint.x());
- h = rect.height();
- break;
- default:
- result = getRect(beginPoint,endPoint);
- return result;
- break;
- }
- return QRect(x,y,w,h); //获取选区
- }
- int fullScreenWidget::getMinValue(int num1, int num2)
- {
- return num1<num2?num1:num2;
- }
- void fullScreenWidget::drawSelectedPixmap(void)
- {
- painter.drawRect(selectedRect); //画选中的矩形框
- shotPixmap = loadPixmap.copy(selectedRect); //更新选区的Pixmap
- if(selectedRect.width() > 0 && selectedRect.height()){
- painter.drawPixmap(selectedRect.topLeft(),shotPixmap); //画选中区域的图片
- }
- draw8ControlPoint(selectedRect); //画出选区的8个控制点
- }
- void fullScreenWidget::drawXYWHInfo(void)
- {
- int x,y;
- QColor color = QColor(239,234,228,200);
- QRect rect;
- QString strTipsText;
- switch(currentShotState){
- case beginShot:
- case finishShot:
- case beginMoveShot:
- case finishMoveShot:
- case beginControl:
- case finishControl:
- x = selectedRect.x() + 5;
- y = selectedRect.y() > infoHeight ? selectedRect.y()-infoHeight:selectedRect.y();
- rect = QRect(x,y,infoWidth,infoHeight);
- strTipsText = QString(tr(" 坐标信息\n x:%1 y:%2\n w:%3 h:%4")).arg(selectedRect.x(),4).arg(selectedRect.y(),4)
- .arg(selectedRect.width(),4).arg(selectedRect.height(),4);
- painter.fillRect(rect,color);
- painter.setPen(QPen(Qt::black));//设置画笔的颜色为黑色
- painter.drawText(rect,Qt::AlignLeft|Qt::AlignVCenter,strTipsText);
- break;
- default:
- break;
- }
- }
您可以下载下来,进行测试使用。解压文件后,使用qtcreator工具进行加载screenshot.pro文件。执行qmake,build,run。即可。
注:因我提供的源代码在ubuntu操作系统上编写,如果您使用的是windows操作系统,可能需要qtcreator修改字符集为uft-8即可。本代码使用的是qt4.6.2进行编译,使用emacs编辑器进行编写。