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

一、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》

 #ifndef WIDGET_H
#define WIDGET_H #include <QWidget> namespace Ui {
class Widget;
} class Widget : public QWidget
{
Q_OBJECT public:
explicit Widget(QWidget *parent = );
~Widget(); private slots:
void on_buttonRead_clicked(); void on_buttonWrite_clicked(); private:
Ui::Widget *ui;
}; #endif // WIDGET_H

widget.h

 #include "widget.h"
#include "ui_widget.h"
#include <QFile>
#include <QFileDialog>
#include <QFileInfo>
#include <QDebug>
#include <QDateTime>
#include <QDataStream> Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
} Widget::~Widget()
{
delete ui;
} 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
//读文件,默认只识别utf8编码
QByteArray array = file.readAll();
//显示到编辑区
//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(); //获取文件信息
QFileInfo info(path);
qDebug() << "文件名字:" << info.fileName().toUtf8().data();
qDebug() << "文件后缀:" << info.suffix();
qDebug() << "文件大小:" << info.size();
qDebug() << "文件创建时间:" <<
info.created().toString("yyyy-MM-dd hh:mm:ss"); //2016-01-04 15:13:00 } } 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();
//写文件
// QString -> QByteArray
//file.write(str.toUtf8()); //QString -> c++ string -> char *
//file.write(str.toStdString().data()); //转换为本地平台编码
file.write(str.toLocal8Bit()); //QString -> QByteArray
QString buf = "";
QByteArray a = buf.toUtf8(); //中文
a = buf.toLocal8Bit(); //本地编码 //QByteArray -> char *
char *b = a.data(); //char * -> QString
char *p = "abc";
QString c = QString(p); } file.close(); } }

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》

 #ifndef WIDGET_H
#define WIDGET_H #include <QWidget> namespace Ui {
class Widget;
} class Widget : public QWidget
{
Q_OBJECT public:
explicit Widget(QWidget *parent = );
~Widget(); void writeData();
void readData(); private:
Ui::Widget *ui;
}; #endif // WIDGET_H

widget.h

 #include "widget.h"
#include "ui_widget.h"
#include <QDataStream>
#include <QTextStream>
#include <QFile>
#include <QDebug>
#define cout qDebug() << "[" << __FILE__ <<":" << __LINE__ << "]" Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this); writeData();
readData();
} Widget::~Widget()
{
delete ui;
} void Widget::writeData()
{
//创建文件对象
QFile file("../test.txt"); //打开文件, 只写方式打开
bool isOk = file.open(QIODevice::WriteOnly);
if(true == isOk)
{
//创建数据流,和file文件关联
//往数据流中写数据,相当于往文件里写数据
QDataStream stream(&file); stream << QString("主要看气质") << ; file.close(); } } void Widget::readData()
{
//创建文件对象
QFile file("../test.txt"); //打开文件, 只读方式打开
bool isOk = file.open(QIODevice::ReadOnly);
if(true == isOk)
{
//创建数据流,和file文件关联
//往数据流中读数据,相当于往文件里读数据
QDataStream stream(&file);
//读的时候,按写的顺序取数据
QString str;
int a;
stream >> str >> a;
//qDebug() << str.toUtf8().data() << a;
cout << str.toUtf8().data() << a; file.close(); }
}

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》

 #ifndef WIDGET_H
#define WIDGET_H #include <QWidget> namespace Ui {
class Widget;
} class Widget : public QWidget
{
Q_OBJECT public:
explicit Widget(QWidget *parent = );
~Widget(); void writeData();
void readData(); private slots:
void on_pushButton_clicked(); private:
Ui::Widget *ui;
}; #endif // WIDGET_H

widget.h

 #include "widget.h"
#include "ui_widget.h"
#include <QTextStream>
#include <QFile>
#include <QDebug>
#include <QFileDialog>
#include <QBuffer>
#define cout qDebug() << "[" << __FILE__ <<":" << __LINE__ << "]" Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
writeData(); readData();
} Widget::~Widget()
{
delete ui;
} 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("主要看气质") << ; 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; cout << str.toUtf8().data() << a; 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();
} } }

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》

 #ifndef WIDGET_H
#define WIDGET_H #include <QWidget> namespace Ui {
class Widget;
} class Widget : public QWidget
{
Q_OBJECT public:
explicit Widget(QWidget *parent = );
~Widget(); private:
Ui::Widget *ui;
}; #endif // WIDGET_H

widget.h

 #include "widget.h"
#include "ui_widget.h"
#include <QBuffer>//内存文件
#include <QDebug>
#include <QDataStream> Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this); QByteArray array;
QBuffer memFile(&array); //创建内存文件
memFile.open(QIODevice::WriteOnly); memFile.write("");
memFile.write(""); memFile.close(); qDebug() << memFile.buffer();
qDebug() << "array" << array; QBuffer memFile1;
memFile1.open(QIODevice::WriteOnly);
QDataStream stream(&memFile1);
stream << QString("测试") << ;
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; } Widget::~Widget()
{
delete ui;
}

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》

 #ifndef CHESSWIDGET_H
#define CHESSWIDGET_H #include <QWidget> class ChessWidget : public QWidget
{
Q_OBJECT public:
ChessWidget(QWidget *parent = );
~ChessWidget(); protected:
//重写绘图事件
void paintEvent(QPaintEvent *);
//重写鼠标按下事件
void mousePressEvent(QMouseEvent *e); private:
int gridW; //棋盘水平方向一个格子的宽度
int gridH; //棋盘水平方向一个格子的高度
int startX; //棋盘起点x坐标
int startY; //棋盘起点y坐标 int chessX, chessY; //棋盘下标 }; #endif // CHESSWIDGET_H

chesswidget.h

 #include "chesswidget.h"
#include <QPainter>
#include <QPen>
#include <QMouseEvent>
#include <QDebug> ChessWidget::ChessWidget(QWidget *parent)
: QWidget(parent)
{
chessX = -;
chessY = -;
} ChessWidget::~ChessWidget()
{ } void ChessWidget::paintEvent(QPaintEvent *)
{
gridW = width()/; //窗口宽度分10份
gridH = height()/; //窗口高度分10份 //棋盘起点坐标
startX = gridW;
startY = gridH; QPainter p(this); //创建画家,指定窗口为绘图设备 //背景图
p.drawPixmap(rect(), QPixmap(":/new/prefix1/Image/bk.jpg")); //设置画笔
QPen pen;
pen.setWidth(); //线宽
p.setPen(pen); //将画笔交给画家 //取中间8份画棋盘
for(int i = ; i <= ; i++)
{
//横线
p.drawLine(startX, startY+i*gridH, startX+*gridW, startY+i*gridH); //竖线
p.drawLine(startX+i*gridW, startY, startX+i*gridW, startY+*gridH);
} //画棋子
if(chessX != - && chessY != -)
{
p.drawPixmap(startX+chessX*gridW, startY+chessY*gridH,
gridW, gridH,
QPixmap(":/new/prefix1/Image/face.png")
);
}
} void ChessWidget::mousePressEvent(QMouseEvent *e)
{
//获取点击的坐标
int x = e->x();
int y = e->y(); // 要保证点击点在棋盘范围里面
if(x >= startX && x <= startX+*gridW
&& y >= startY && y <= startX+*gridH)
{
// 棋盘的位置转换转换为坐标下标值
// 类似于a[i][j]的i和j
chessX = (x - startX)/gridW;
chessY = (y - startY)/gridH;
qDebug() << chessX << chessY; //更新窗口,间接调用paintEvent()
update();
}
}

chesswidget.cpp

界面编程之QT的文件操作20180729的更多相关文章

  1. 界面编程之QT的数据库操作20180801

    /*******************************************************************************************/ 一.数据库连 ...

  2. 界面编程之QT窗口系统20180726

    /*******************************************************************************************/ 一.坐标系统 ...

  3. 界面编程之QT的基本介绍与使用20180722

    /*******************************************************************************************/ 一.qt介绍 ...

  4. 界面编程之QT的线程20180731

    /*******************************************************************************************/ 一.为什么需 ...

  5. 界面编程之QT的Socket通信20180730

    /*******************************************************************************************/ 一.linu ...

  6. 界面编程之QT的信号与槽20180725

    /*******************************************************************************************/ 一.指定父对 ...

  7. 界面编程之QT绘图和绘图设备20180728

    /*******************************************************************************************/ 一.绘图 整 ...

  8. 界面编程之QT的事件20180727

    /*******************************************************************************************/ 一.事件 1 ...

  9. QT核心编程之Qt线程 (c)

    QT核心编程之Qt线程是本节要介绍的内容,QT核心编程我们要分几个部分来介绍,想参考更多内容,请看末尾的编辑推荐进行详细阅读,先来看本篇内容. Qt对线程提供了支持,它引入了一些基本与平台无关的线程类 ...

随机推荐

  1. Python学习系列:PyCharm CE 安装与测试

    开坑啦开坑啦~最近比赛要用Python了,开始强行学习. Mac下PyCharm CE 安装 先去百度PyCharm,一个很好用IDE,下载免费版的就够用啦: https://www.jetbrain ...

  2. POJ 1988&&2236

    并查集,如果只是朴素的路径压缩,那么也就是一句话的事情. 但是,一般都没有这种仁慈的裸题(假的,多了去了) 1988:带权并查集,贼鸡儿像Luogu的那道杨威利的并查集(好像是叫银河英雄传说) 开两个 ...

  3. CSS布局的一些技巧

    max-width 通常使元素水平居中用的较多的方法为: #main { width: 600px; margin: 0 auto; } 但是,当浏览器窗口比元素的宽度还要窄时,浏览器会显示一个水平滚 ...

  4. flask-login 整合 pyjwt + json 简易flask框架

    现在很多框架都实现前后端分离,主要为了适应以下几个目的: 1,前后端的分离,可以使前端开发和后端开发更加分工明确,而不是后端还需要在视图模板中加入很多{% XXXX %}标签 2,是为了适应跨域调用或 ...

  5. JavaScript 为什么不要使用 eval

    本文内容 eval 隐藏的 eval 安全问题 结论 参考资料   eval eval 函数是一个高等级的函数,它与任何对象都无关.其参数,如果是一个字符串表达式,那么该函数计算表达式的值:如果是一个 ...

  6. Azure 基础:自定义 Table storage 查询条件

    本文是在 <Azure 基础:Table storage> 一文的基础上介绍如何自定义 Azure Table storage 的查询过滤条件.如果您还不太清楚 Azure Table s ...

  7. PAT甲题题解-1106. Lowest Price in Supply Chain (25)-(dfs计算树的最小层数)

    统计树的最小层数以及位于该层数上的叶子节点个数即可. 代码里建树我用了邻接链表的存储方式——链式前向星,不了解的可以参考,非常好用: http://www.cnblogs.com/chenxiwenr ...

  8. Linux内核分析第五章读书笔记

    第五章 系统调用 在操作系统中,内核提供了用户进程与内核进行交互的一组接口,这些接口在应用程序和内核之间扮演了使者的角色,保证系统稳定可靠,避免应用程序肆意妄行. 5.1 与内核通信 系统调用在用户空 ...

  9. c# dataGridView cell添加下拉框

    应用场景: dataGridView需要某一个cell变成下拉框样式. 思路详解: dataGridVie添加固定格式的row. 代码: DataGridViewRow row = new DataG ...

  10. Daily Scrum - 12/0809

    Meeting Minutes (08的Scrum报告放在word里,publish没有成功,所以这是08-09的报告,抱歉…): 卡片翻转的效果确认完成: 按钮蓄力的效果确认完成: 按钮上移的效果确 ...