界面编程之QT的文件操作20180729

/*******************************************************************************************/

一、QT文件操作

文件操作是应用程序必不可少的 部分。Qt 作为一个通用开发库,提供了跨平台的文件操作能力。

Qt 通过QIODevice提供了对 I/O 设备的抽象,这些设备具有读写字节块的能力。

qt中的文件(IO)层次:

QIODevice是基类,下面派生出了各个子类,其中:

  QBuffer 类似与数组,操作内存缓冲区

  QProcess 类似system函数,开启一个其他进程

  QFileDevice 普通文件,类似文件描述符

  QAbsrtacSocket 网络套接字

具体见图1:

 

具体说明:

         QIODevice:所有 I/O 设备类的父类,提供了字节块读写的通用操作以及基本接口;

         QFileDevice:Qt5新增加的类,提供了有关文件操作的通用实现。

         QFlie:访问本地文件或者嵌入资源;

         QTemporaryFile:创建和访问本地文件系统的临时文件;

         QBuffer:读写QbyteArray, 内存文件;

         QProcess:运行外部程序,处理进程间通讯;

         QAbstractSocket:所有套接字类的父类;

         QTcpSocket:TCP协议网络数据传输;

         QUdpSocket:传输 UDP 报文;

         QSslSocket:使用 SSL/TLS 传输数据;

文件操作分类:

         顺序访问设备:

是指它们的数据只能访问一遍:从头走到尾,从第一个字节开始访问,直到最后一个字节,中途不能返回去读取上一个字节,这其中,QProcess、QTcpSocket、QUdpSoctet和QSslSocket是顺序访问设备。

         随机访问设备:

可以访问任意位置任意次数,还可以使用QIODevice::seek()函数来重新定位文件访问位置指针,QFile、QTemporaryFile和QBuffer是随机访问设备,

/*******************************************************************************************/

二、QFile文件操作(基本文件操作)

文件操作是应用程序必不可少的部分。Qt 作为一个通用开发库,提供了跨平台的文件操作能力。在所有的 I/O 设备中,

文件 I/O 是最重要的部分之一。因为我们大多数的程序依旧需要首先访问本地文件(当然,在云计算大行其道的将来,这一观点可能改变)。

QFile提供了从文件中读取和写入数据的能力。

我们通常会将文件路径作为参数传给QFile的构造函数。不过也可以在创建好对象最后,使用setFileName()来修改。QFile需要使用 / 作为文件分隔符,

不过,它会自动将其转换成操作系统所需要的形式。例如 C:/windows 这样的路径在 Windows 平台下同样是可以的。

QFile主要提供了有关文件的各种操作,比如打开文件、关闭文件、刷新文件等。我们可以使用QDataStream或QTextStream类来读写文件,

也可以使用QIODevice类提供的read()、readLine()、readAll()以及write()这样的函数。

值得注意的是,有关文件本身的信息,比如文件名、文件所在目录的名字等,则是通过QFileInfo获取,而不是自己分析文件路径字符串。

1.QFile读文件:

void Widget::on_buttonRead_clicked()

{

    QString path = QFileDialog::getOpenFileName(this,

                "open", "../", "TXT(*.txt)");//获取文件路径

    if(path.isEmpty() == false)

    {

        //创建文件对象

        QFile file(path);

        //打开文件,只读方式

        bool isOk = file.open(QIODevice::ReadOnly);

        if(isOk == true)

        {

#if 0

            //读文件

            QByteArray array = file.readAll();//一次性读完,这个读的接口默认都的文本是只识别utf8编码

                                                                                                                //,要读其他编码的要借助于后面讲的文本流

                           

                            //显示到编辑区

            //ui->textEdit->setText(QString(array));

            ui->textEdit->setText(array);//内部自动转换了类型

#endif

            QByteArray array;

            while( file.atEnd() == false)

            {

                //读一行

                array += file.readLine();//默认读完一行,换行符也读进去了

            }

            ui->textEdit->setText(array);

        }

        //关闭文件

        file.close();

    }

}

2.QFile写文件:

void Widget::on_buttonWrite_clicked()

{

         //获取保存文件的路径

    QString path = QFileDialog::getSaveFileName(this, "save", "../", "TXT(*.txt)");

    if(path.isEmpty() == false)

    {

        QFile file; //创建文件对象

        //关联文件名字

        file.setFileName(path);

        //打开文件(没有则创建),只写方式

        bool isOk = file.open(QIODevice::WriteOnly);

        if(isOk == true)

        {

            //获取编辑区内容

            QString str = ui->textEdit->toPlainText();//qt里文本用的是utf8

            //写文件

            // QString -> QByteArray

            //file.write(str.toUtf8());//保存的结果是utf8的文本,可以正常打开并显示,无乱码

            //QString -> c++ string -> char *

            //file.write(str.toStdString().data());//保存的结果是utf8的文本,可以正常打开并显示,无乱码

            //转换为本地平台编码(win默认编码,一般是ansi),可以正常打开并显示,无乱码

            file.write(str.toLocal8Bit());

            //QString -> QByteArray 转换方法:

            QString buf = "123";

            QByteArray a = buf.toUtf8(); //中文//QByteArray是utf8格式的文本

            a = buf.toLocal8Bit(); //本地编码(win默认编码)//QByteArray是本地编码的文本

            //QByteArray -> char *

            char *b = a.data();

            //char * -> QString

            char *p = "abc";

            QString c = QString(p);

        }

        file.close();

    }

}

3.QfileInfo获取文件信息

        //获取文件信息

        QFileInfo info(path);

        qDebug() << "文件名字:" << info.fileName().toUtf8().data();//转换为utf8才能打印出来

        qDebug() << "文件后缀:" << info.suffix();

        qDebug() << "文件大小:" << info.size();

        qDebug() << "文件创建时间:" <<

        info.created().toString("yyyy-MM-dd hh:mm:ss"); //2016-01-04 15:13:00       

                        

具体见《QFile》

 1 #ifndef WIDGET_H
 2 #define WIDGET_H
 3 
 4 #include <QWidget>
 5 
 6 namespace Ui {
 7 class Widget;
 8 }
 9 
10 class Widget : public QWidget
11 {
12     Q_OBJECT
13 
14 public:
15     explicit Widget(QWidget *parent = 0);
16     ~Widget();
17 
18 private slots:
19     void on_buttonRead_clicked();
20 
21     void on_buttonWrite_clicked();
22 
23 private:
24     Ui::Widget *ui;
25 };
26 
27 #endif // WIDGET_H
widget.h
  1 #include "widget.h"
  2 #include "ui_widget.h"
  3 #include <QFile>
  4 #include <QFileDialog>
  5 #include <QFileInfo>
  6 #include <QDebug>
  7 #include <QDateTime>
  8 #include <QDataStream>
  9 
 10 Widget::Widget(QWidget *parent) :
 11     QWidget(parent),
 12     ui(new Ui::Widget)
 13 {
 14     ui->setupUi(this);
 15 }
 16 
 17 Widget::~Widget()
 18 {
 19     delete ui;
 20 }
 21 
 22 void Widget::on_buttonRead_clicked()
 23 {
 24     QString path = QFileDialog::getOpenFileName(this,
 25                 "open", "../", "TXT(*.txt)");
 26     if(path.isEmpty() == false)
 27     {
 28         //文件对象
 29         QFile file(path);
 30 
 31         //打开文件,只读方式
 32         bool isOk = file.open(QIODevice::ReadOnly);
 33         if(isOk == true)
 34         {
 35 #if 0
 36             //读文件,默认只识别utf8编码
 37             QByteArray array = file.readAll();
 38             //显示到编辑区
 39             //ui->textEdit->setText(QString(array));
 40             ui->textEdit->setText(array);
 41 #endif
 42 
 43             QByteArray array;
 44             while( file.atEnd() == false)
 45             {
 46                 //读一行
 47                 array += file.readLine();
 48             }
 49             ui->textEdit->setText(array);
 50 
 51         }
 52 
 53         //关闭文件
 54         file.close();
 55 
 56         //获取文件信息
 57         QFileInfo info(path);
 58         qDebug() << "文件名字:" << info.fileName().toUtf8().data();
 59         qDebug() << "文件后缀:" << info.suffix();
 60         qDebug() << "文件大小:" << info.size();
 61         qDebug() << "文件创建时间:" <<
 62          info.created().toString("yyyy-MM-dd hh:mm:ss"); //2016-01-04 15:13:00
 63 
 64     }
 65 
 66 
 67 }
 68 
 69 void Widget::on_buttonWrite_clicked()
 70 {
 71     QString path = QFileDialog::getSaveFileName(this, "save", "../", "TXT(*.txt)");
 72     if(path.isEmpty() == false)
 73     {
 74         QFile file; //创建文件对象
 75         //关联文件名字
 76         file.setFileName(path);
 77 
 78         //打开文件,只写方式
 79         bool isOk = file.open(QIODevice::WriteOnly);
 80         if(isOk == true)
 81         {
 82             //获取编辑区内容
 83             QString str = ui->textEdit->toPlainText();
 84             //写文件
 85             // QString -> QByteArray
 86             //file.write(str.toUtf8());
 87 
 88             //QString -> c++ string -> char *
 89             //file.write(str.toStdString().data());
 90 
 91             //转换为本地平台编码
 92             file.write(str.toLocal8Bit());
 93 
 94 
 95             //QString -> QByteArray
 96             QString buf = "123";
 97             QByteArray a = buf.toUtf8(); //中文
 98             a = buf.toLocal8Bit(); //本地编码
 99 
100             //QByteArray -> char *
101             char *b = a.data();
102 
103             //char * -> QString
104             char *p = "abc";
105             QString c = QString(p);
106 
107 
108         }
109 
110         file.close();
111 
112     }
113 
114 
115 
116 
117 }
widget.cpp

/*******************************************************************************************/

三、QDataStream读写文件(二进制读写文件)

以二进制的方法操作文件,就要借助QDataStream

由于是操作文件,所以还得用到QFile

void Widget::writeData()

{

    //创建文件对象

    QFile file("../test.txt");

    //打开文件, 只写方式打开

    bool isOk = file.open(QIODevice::WriteOnly);

    if(true == isOk)

    {

        //创建数据流,和file文件关联

        //往数据流中写数据,相当于往文件里写数据

        QDataStream stream(&file);

        stream << QString("主要看气质") << 250;//结果文件里都是不可见的二进制数据

        file.close();

    }

}

#define cout qDebug() << "[" << __FILE__ <<":" << __LINE__ << "]"

void Widget::readData()

{

    //创建文件对象

    QFile file("../test.txt");

    //打开文件, 只读方式打开

    bool isOk = file.open(QIODevice::ReadOnly);

    if(true == isOk)

    {

        //创建数据流,和file文件关联

        //往数据流中读数据,相当于往文件里读数据

        QDataStream stream(&file);

        //读的时候,按写的顺序取数据

        QString str;//先取出str,因为这个是之前先输入的

        int a;

        stream >> str >> a;

        //qDebug() << str.toUtf8().data() << a;

        cout << str.toUtf8().data() << a;

        file.close();

    }

}

具体见《QDataStream》

 1 #ifndef WIDGET_H
 2 #define WIDGET_H
 3 
 4 #include <QWidget>
 5 
 6 namespace Ui {
 7 class Widget;
 8 }
 9 
10 class Widget : public QWidget
11 {
12     Q_OBJECT
13 
14 public:
15     explicit Widget(QWidget *parent = 0);
16     ~Widget();
17 
18     void writeData();
19     void readData();
20 
21 private:
22     Ui::Widget *ui;
23 };
24 
25 #endif // WIDGET_H
widget.h
 1 #include "widget.h"
 2 #include "ui_widget.h"
 3 #include <QDataStream>
 4 #include <QTextStream>
 5 #include <QFile>
 6 #include <QDebug>
 7 #define cout qDebug() << "[" << __FILE__ <<":" << __LINE__ << "]"
 8 
 9 Widget::Widget(QWidget *parent) :
10     QWidget(parent),
11     ui(new Ui::Widget)
12 {
13     ui->setupUi(this);
14 
15     writeData();
16     readData();
17 }
18 
19 Widget::~Widget()
20 {
21     delete ui;
22 }
23 
24 void Widget::writeData()
25 {
26     //创建文件对象
27     QFile file("../test.txt");
28 
29     //打开文件, 只写方式打开
30     bool isOk = file.open(QIODevice::WriteOnly);
31     if(true == isOk)
32     {
33         //创建数据流,和file文件关联
34         //往数据流中写数据,相当于往文件里写数据
35         QDataStream stream(&file);
36 
37         stream << QString("主要看气质") << 250;
38 
39         file.close();
40 
41     }
42 
43 }
44 
45 void Widget::readData()
46 {
47     //创建文件对象
48     QFile file("../test.txt");
49 
50     //打开文件, 只读方式打开
51     bool isOk = file.open(QIODevice::ReadOnly);
52     if(true == isOk)
53     {
54         //创建数据流,和file文件关联
55         //往数据流中读数据,相当于往文件里读数据
56         QDataStream stream(&file);
57         //读的时候,按写的顺序取数据
58         QString str;
59         int a;
60         stream >> str >> a;
61         //qDebug() << str.toUtf8().data() << a;
62         cout << str.toUtf8().data() << a;
63 
64         file.close();
65 
66     }
67 }
widget.cpp

/*******************************************************************************************/

四、QTextStream操作文件(文本的方式操作文件)

  上一节我们介绍了有关二进制文件的读写。二进制文件比较小巧,却不是人可读的格式。而文本文件是一种人可读的文件。

为了操作这种文件,我们需要使用QTextStream类。QTextStream和QDataStream的使用类似,只不过它是操作纯文本文件的。

  QTextStream会自动将 Unicode 编码同操作系统的编码进行转换,这一操作对开发人员是透明的。它也会将换行符进行转换,

同样不需要自己处理。QTextStream使用 16 位的QChar作为基础的数据存储单位,同样,它也支持 C++ 标准类型,如 int 等。

实际上,这是将这种标准类型与字符串进行了相互转换。

通过文本的方式操作文件,这样的好处是读写的时候可以指定编码

QTextStream只能通过文本的方式操作文件

void Widget::writeData()

{

    QFile file;

    file.setFileName("../demo.txt");

    bool isOk = file.open(QIODevice::WriteOnly);

    if(true == isOk)

    {

        QTextStream stream(&file);

        //指定编码

        stream.setCodec("UTF-8");

                   //默认以系统平台的编码打印

        stream << QString("主要看气质") << 250;//格式化输出为可见字符,可以显示,类似格式化打印

        file.close();

    }

}

void Widget::readData()

{

    QFile file;

    file.setFileName("../demo.txt");

    bool isOk = file.open(QIODevice::ReadOnly);

    if(true == isOk)

    {

        QTextStream stream(&file);

        //指定编码,前面指定以什么编码读,最好后面也指定以什么编码读

        stream.setCodec("UTF-8");

        QString str;//

        int a;

        stream >> str >> a;//这种方式读取,由于文件中写入的都是文本字符串,所以第一次就

                     //把内容全部读取给str了,a根本就获取不到内容。所以不能使用这种方式,一般使用函数

                     //的方式,见下面的函数

                    

        cout << str.toUtf8().data() << a;//显示的时候还是需要转换为utf8

        file.close();

    }

}

void Widget::on_pushButton_clicked()

{

    QString path = QFileDialog::getOpenFileName(this,

             "open", "../"  );

    if(false == path.isEmpty())

    {

        QFile file;

        file.setFileName(path);

        bool isOk = file.open(QIODevice::ReadOnly);

        if(true == isOk)

        {

            QTextStream stream(&file);

            //指定编码

            stream.setCodec("UTF-8");

            QString str = stream.readAll();//使用函数读取自己想要的内容

            ui->textEdit->setText(str);

            file.close();

        }

    }

}

具体见《QTextStream》

 1 #ifndef WIDGET_H
 2 #define WIDGET_H
 3 
 4 #include <QWidget>
 5 
 6 namespace Ui {
 7 class Widget;
 8 }
 9 
10 class Widget : public QWidget
11 {
12     Q_OBJECT
13 
14 public:
15     explicit Widget(QWidget *parent = 0);
16     ~Widget();
17 
18     void writeData();
19     void readData();
20 
21 private slots:
22     void on_pushButton_clicked();
23 
24 private:
25     Ui::Widget *ui;
26 };
27 
28 #endif // WIDGET_H
widget.h
 1 #include "widget.h"
 2 #include "ui_widget.h"
 3 #include <QTextStream>
 4 #include <QFile>
 5 #include <QDebug>
 6 #include <QFileDialog>
 7 #include <QBuffer>
 8 #define cout qDebug() << "[" << __FILE__ <<":" << __LINE__ << "]"
 9 
10 Widget::Widget(QWidget *parent) :
11     QWidget(parent),
12     ui(new Ui::Widget)
13 {
14     ui->setupUi(this);
15     writeData();
16 
17     readData();
18 }
19 
20 Widget::~Widget()
21 {
22     delete ui;
23 }
24 
25 void Widget::writeData()
26 {
27     QFile file;
28     file.setFileName("../demo.txt");
29 
30     bool isOk = file.open(QIODevice::WriteOnly);
31     if(true == isOk)
32     {
33         QTextStream stream(&file);
34         //指定编码
35         stream.setCodec("UTF-8");
36 
37         stream << QString("主要看气质") << 250;
38 
39         file.close();
40     }
41 }
42 
43 void Widget::readData()
44 {
45     QFile file;
46     file.setFileName("../demo.txt");
47 
48     bool isOk = file.open(QIODevice::ReadOnly);
49     if(true == isOk)
50     {
51         QTextStream stream(&file);
52         //指定编码
53         stream.setCodec("UTF-8");
54         QString str;
55         int a;
56         stream >> str >> a;
57 
58         cout << str.toUtf8().data() << a;
59 
60         file.close();
61 
62     }
63 }
64 
65 void Widget::on_pushButton_clicked()
66 {
67     QString path = QFileDialog::getOpenFileName(this,
68              "open", "../"  );
69     if(false == path.isEmpty())
70     {
71         QFile file;
72         file.setFileName(path);
73 
74         bool isOk = file.open(QIODevice::ReadOnly);
75         if(true == isOk)
76         {
77             QTextStream stream(&file);
78             //指定编码
79             stream.setCodec("UTF-8");
80 
81             QString str = stream.readAll();
82             ui->textEdit->setText(str);
83 
84             file.close();
85         }
86 
87     }
88 
89 
90 }
widget.cpp

/*******************************************************************************************/

四、QBuffer

QBuffer也叫内存文件,放在内存里面的

Widget::Widget(QWidget *parent) :

    QWidget(parent),

    ui(new Ui::Widget)

{

    ui->setupUi(this);

    QByteArray array;

    QBuffer memFile(&array); //创建内存文件,指定了缓冲区&array,后续读写操作的都是这个&array

    memFile.open(QIODevice::WriteOnly);

    memFile.write("11111111111111111");//实际上是写到缓冲区里面

    memFile.write("22222222222222222222");//注意两个之间没有换行符

    memFile.close();

    qDebug() << memFile.buffer();//取出数据

    qDebug() << "array" << array;//前后打印结果是一样的

         //内存文件配合数据流的使用

    QBuffer memFile1;

    memFile1.open(QIODevice::WriteOnly);

    QDataStream stream(&memFile1);//内存文件在数据流中的使用

    stream << QString("测试") << 250;

    memFile1.close();

    qDebug() <<  memFile1.buffer();//输出显示的是一堆二进制数据

        

    memFile1.open(QIODevice::ReadOnly);

    QDataStream in;

    in.setDevice(&memFile1);

    QString str;

    int a;

    in >> str >> a;

    memFile1.close();

    qDebug() << str.toUtf8().data() << a;

}

具体见《QBuffer》

 1 #ifndef WIDGET_H
 2 #define WIDGET_H
 3 
 4 #include <QWidget>
 5 
 6 namespace Ui {
 7 class Widget;
 8 }
 9 
10 class Widget : public QWidget
11 {
12     Q_OBJECT
13 
14 public:
15     explicit Widget(QWidget *parent = 0);
16     ~Widget();
17 
18 
19 private:
20     Ui::Widget *ui;
21 };
22 
23 #endif // WIDGET_H
widget.h
 1 #include "widget.h"
 2 #include "ui_widget.h"
 3 #include <QBuffer>//内存文件
 4 #include <QDebug>
 5 #include <QDataStream>
 6 
 7 Widget::Widget(QWidget *parent) :
 8     QWidget(parent),
 9     ui(new Ui::Widget)
10 {
11     ui->setupUi(this);
12 
13     QByteArray array;
14     QBuffer memFile(&array); //创建内存文件
15     memFile.open(QIODevice::WriteOnly);
16 
17     memFile.write("11111111111111111");
18     memFile.write("22222222222222222222");
19 
20     memFile.close();
21 
22     qDebug() << memFile.buffer();
23     qDebug() << "array" << array;
24 
25 
26     QBuffer memFile1;
27     memFile1.open(QIODevice::WriteOnly);
28     QDataStream stream(&memFile1);
29     stream << QString("测试") << 250;
30     memFile1.close();
31 
32     qDebug() <<  memFile1.buffer();
33 
34     memFile1.open(QIODevice::ReadOnly);
35     QDataStream in;
36     in.setDevice(&memFile1);
37     QString str;
38     int a;
39     in >> str >> a;
40     memFile1.close();
41 
42     qDebug() << str.toUtf8().data() << a;
43 
44 }
45 
46 Widget::~Widget()
47 {
48     delete ui;
49 }
widget.cpp

/*******************************************************************************************/

五、实例___棋盘的制作

使用绘图实现

核心算法:

1.等分窗口的宽和高,形成一个个相同的格子,同时记录格子的宽和高方便绘图

         gridW = width()/10;  //窗口宽度分10份

    gridH = height()/10; //窗口高度分10份

    //棋盘起点坐标

    startX = gridW;

    startY = gridH;

2.计算鼠标落在哪个格子上,使用除法,鼠标的坐标除以格子的宽和高取整就知道落在哪个格子上

知道落在哪个格子上,再乘以对应的宽和高就知道绘图的坐标

         {

                   // 棋盘的位置转换转换为坐标下标值

                   // 类似于a[i][j]的i和j

                   chessX = (x - startX)/gridW;

                   chessY = (y - startY)/gridH;

                   qDebug() << chessX << chessY;

                   //更新窗口,间接调用paintEvent()

                   update();

         }

    //画棋子

    if(chessX != -1 && chessY != -1)

    {

        p.drawPixmap(startX+chessX*gridW, startY+chessY*gridH,

                     gridW, gridH,

                     QPixmap(":/new/prefix1/Image/face.png")

                     );

    }

具体见《ChessDemo》

 1 #ifndef CHESSWIDGET_H
 2 #define CHESSWIDGET_H
 3 
 4 #include <QWidget>
 5 
 6 class ChessWidget : public QWidget
 7 {
 8     Q_OBJECT
 9 
10 public:
11     ChessWidget(QWidget *parent = 0);
12     ~ChessWidget();
13 
14 protected:
15     //重写绘图事件
16     void paintEvent(QPaintEvent *);
17     //重写鼠标按下事件
18     void mousePressEvent(QMouseEvent *e);
19 
20 private:
21     int gridW;  //棋盘水平方向一个格子的宽度
22     int gridH;  //棋盘水平方向一个格子的高度
23     int startX; //棋盘起点x坐标
24     int startY; //棋盘起点y坐标
25 
26     int chessX, chessY; //棋盘下标
27 
28 };
29 
30 #endif // CHESSWIDGET_H
chesswidget.h
 1 #include "chesswidget.h"
 2 #include <QPainter>
 3 #include <QPen>
 4 #include <QMouseEvent>
 5 #include <QDebug>
 6 
 7 ChessWidget::ChessWidget(QWidget *parent)
 8     : QWidget(parent)
 9 {
10     chessX = -1;
11     chessY = -1;
12 }
13 
14 ChessWidget::~ChessWidget()
15 {
16 
17 }
18 
19 void ChessWidget::paintEvent(QPaintEvent *)
20 {
21     gridW = width()/10;  //窗口宽度分10份
22     gridH = height()/10; //窗口高度分10份
23 
24     //棋盘起点坐标
25     startX = gridW;
26     startY = gridH;
27 
28     QPainter p(this); //创建画家,指定窗口为绘图设备
29 
30     //背景图
31     p.drawPixmap(rect(), QPixmap(":/new/prefix1/Image/bk.jpg"));
32 
33     //设置画笔
34     QPen pen;
35     pen.setWidth(4); //线宽
36     p.setPen(pen);  //将画笔交给画家
37 
38     //取中间8份画棋盘
39     for(int i = 0; i <= 8; i++)
40     {
41         //横线
42         p.drawLine(startX, startY+i*gridH, startX+8*gridW, startY+i*gridH);
43 
44         //竖线
45         p.drawLine(startX+i*gridW, startY, startX+i*gridW, startY+8*gridH);
46     }
47 
48     //画棋子
49     if(chessX != -1 && chessY != -1)
50     {
51         p.drawPixmap(startX+chessX*gridW, startY+chessY*gridH,
52                      gridW, gridH,
53                      QPixmap(":/new/prefix1/Image/face.png")
54                      );
55     }
56 }
57 
58 void ChessWidget::mousePressEvent(QMouseEvent *e)
59 {
60     //获取点击的坐标
61     int x = e->x();
62     int y = e->y();
63 
64     // 要保证点击点在棋盘范围里面
65     if(x >= startX && x <= startX+8*gridW
66        && y >= startY && y <= startX+8*gridH)
67     {
68         // 棋盘的位置转换转换为坐标下标值
69         // 类似于a[i][j]的i和j
70         chessX = (x - startX)/gridW;
71         chessY = (y - startY)/gridH;
72         qDebug() << chessX << chessY;
73 
74         //更新窗口,间接调用paintEvent()
75         update();
76     }
77 }
chesswidget.cpp
原文地址:https://www.cnblogs.com/yuweifeng/p/9381302.html