界面編程之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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM