Qt basic study notes

Common shortcut keys in Qt

Note: ctrl + /
Run: ctrl + r
Compile: ctrl + b
Help documentation: F1
Automatic alignment: ctrl + i
Switch between .h files and .cpp files with the same name: F4

QPushButtonButton

The <QPushButton> header file needs to be introduced. QPushButton inherits from the QWidget class.

Create a button

// 默认构造
QPushButton * btn = new QPushButton();

// 构造创建按钮 弊端:默认以控件的大小创建窗口
QPushButton* btn2 = new QPushButton("第二个按钮", this); // 通过构造指定父类和文本

show button

btn->show(); // 默认顶层方式弹出,独立的窗口

If you want the button to be displayed in the specified window, you need to specify the parent class

btn->setParent(this); // 将按钮的父类设置为myWidget,使其显示在myWidget窗口中
btn->setText("第一个按钮"); // 按钮的文本

Set the button position.
The coordinates are based on the upper left corner (0, 0)

// 移动按钮至指定坐标处
btn2->move(100, 100);

Window and button size

// 重置窗口大小
resize(600, 400);

// 按钮重置大小
btn2->resize(50,50);

// 设置固定的窗口大小
setFixedSize(600, 400); // 不能通过鼠标拖拽来改变窗口的大小

Set window title

// 设置窗口标题
setWindowTitle("第一个窗口");

object tree

1. When the created object is in the heap area, if the specified object is a class derived from QObject or its subclass, you can put the object into the object tree without managing the release operation.
2. The object tree is constructed with the existing parent class and then the subclass. The destruction sequence is to destruct the subclass first and then the parent class.
3. When there is an output statement in the destructor, the destructor statement of the parent class is printed first, but this does not mean the destructor order. The order of Xigou is still first the child category and then the parent category.
4. The object tree simplifies the memory recycling mechanism to a certain extent.

signals and slots

Advantages of signal slots: loose coupling.
What is loose coupling: The sending end and receiving end of the signal are not related to each other, and the two ends are coupled together through the connect connection.
connect(sender, signal sent, receiver, signal processing (slot));

  1. Parameter 1: The sender of the signal
  2. Parameter 2: The signal sent (the address where the function is stored) (clicked, pressed, released, toggled)
  3. Parameter 3: The receiver of the signal
  4. Parameter 4: Processed slot function (function address)
connect(myBtn, &PushButton::clicked, this, &Widget::close);

// 断开信号, 传参与connect一致
disconnect(btn, &QPushButton::clicked, this, &Widget::classIsOver);

// Qt4版本信号槽的连接
connect(zt, SIGNAL(hungry()), st, SLOT(treat()));

The advantages of the Qt4 version are intuitive. Disadvantage, type is not detected

Custom signals
Custom signals are modified with the signals keyword.
Regulations:
1. There is no return value;
2. It only needs to be declared and does not need to be implemented;
3. Can have parameters;
4. Can be overloaded;

signals:
    // 自定义信号写在这里
    void hungry();
    void hungry(QString foodName); // 信号的重载

Custom slot function
stipulates:
1. No return value;
2. Needs to be declared and implemented;
3. Can have parameters;
4. Overloading can occur;

public slots:
    // 槽函数写在这里,早期版本必须写在这里,Qt5之后可以不使用slots关键字
    void treat();
    void treat(QString foodName); 

The function type needs to be specified when connecting the overloaded slot function.

// 创建一个老师对象
this->zt = new Teacher(this);

// 创建一个学生对象
this->st = new Student(this);

// 有参信号的连接
void (Teacher:: *teacherSignal)(QString) = &Teacher::hungry;
void (Student:: *studentSlots)(QString) = &Student::treat;
connect(zt, teacherSignal, st, studentSlots);

// 无参信号的连接
void (Teacher:: *teacherSignal2)(void) = &Teacher::hungry;
void (Student:: *studentSlots2)(void) = &Student::treat;
connect(zt, teacherSignal2, st, studentSlots2);

Slot functions must have corresponding implementations.
When using, just use connect to connect the signal and slot function together.

Sending signals
using emit

emit zt->hungry(); // 使用emit发送信号
emit zt->hungry("有参的信号");

Connection of signals and slots
1. Signals connect to multiple slot functions
2. Multiple signals connect to the same slot function
3. Signals connect signals
Note: Signals can have more parameters than slots, but they must correspond one to one

lambda expression

    // []标识一个Lambda的开始不能省略
    [=](){
    
     // 值传递
        btn->setText("下课111");
    }();
    [&](){
    
     // 引用传递
        btn2->setText("下课222");
    }();
    [btn](){
    
     // 锁定值传递,只有btn生效
        btn->setText("下课222");
        //btn2->setText("下课222"); // 看不到,报错
    }();
    [=]()mutable{
    
     // 加上mutable关键字,可以修改值传递的拷贝,注意只能修改拷贝,而不是传入值的本身
        btn->setText("下课111");
    }();
    int ret = []()->int{
    
    return 1000;}(); // ->代表Lambda的返回值类型
    qDebug() << ret << endl;

Menu Bar

There can only be at most one menu bar in a program

	// 菜单栏的创建
	QMenuBar *bar = menuBar();
	// 将菜单栏放入窗口中
	setMenuBar(bar);
	
	// 新增菜单
    QMenu * fileMenu = bar->addMenu("文件");
    QMenu * editMenu = bar->addMenu("编辑");

    // 创建菜单项
    QAction* newAction = fileMenu->addAction("新建");
    fileMenu->addSeparator(); // 添加分割线
    QAction* openAction = fileMenu->addAction("打开");

toolbar

There can be multiple toolbars

    QToolBar* toolBar = new QToolBar(this);
    //addToolBar(toolBar); // 将工具栏加载到窗口中,默认位置在上面,可以拖拽
    addToolBar(Qt::LeftToolBarArea, toolBar); // 指定左边

    // 只允许工具栏左右停靠
    toolBar->setAllowedAreas(Qt::LeftToolBarArea | Qt::RightToolBarArea);

    // 设置工具栏浮动
    toolBar->setFloatable(false); // 默认值为 true 可以浮动。设置false不允许浮动

    // 设置不可拖拽,默认可拖拽
    toolBar->setMovable(false);

    // 在工具栏中设置选项
    toolBar->addAction(newAction); // 跟上面fileMenu公用一个
    toolBar->addAction(openAction);
    toolBar->addSeparator(); // 添加分割线
    toolBar->addAction("自己"); // 也可以自己设置一个选项

    // 工具栏中添加控件
    QPushButton * btn = new QPushButton("aa", this);
    toolBar->addWidget(btn); // 将按钮放入工具栏中

Status Bar

There can be multiple

    QStatusBar* stBar = statusBar();
    // 将状态栏设置在窗口中
    setStatusBar(stBar);
    // 往状态栏中放标签控件
    QLabel* label = new QLabel("提示", this);
    stBar->addWidget(label); // 将标签放入状态栏

    QLabel* label2 = new QLabel("右侧提示", this);
    stBar->addPermanentWidget(label2);

riveted parts

    // 铆接部件(浮动窗口)  可以有多个  可拖拽
    QDockWidget* dockWidget = new QDockWidget("浮动",this);
    addDockWidget(Qt::BottomDockWidgetArea, dockWidget); // 围绕核心,根据核心确定位置

    // 设置后期停靠只能上下
    dockWidget->setAllowedAreas(Qt::TopDockWidgetArea | Qt::BottomDockWidgetArea);

Core components

There can only be one

	// 设置中心部件, 只能有一个
    QTextEdit* edit = new QTextEdit(this);
    setCentralWidget(edit); // 设置中心部件到窗口

The layout of each column
Insert image description here

Add resource files

Step 1: Copy the resources to the folder where the project is located.
Step 2: Right-click the project in Qt -> Add New File (Add New...), and the following interface will appear.
Insert image description here
Step 3: Name it yourself. After the addition is successful, the Qt list will Folder with extra resources.
Insert image description here
Step 4: Right-click the .qrc resource file.
Insert image description here
Step 5: Add prefixes to customize. Add the prefix first and then add the file.
Insert image description here
Then save and compile, and you will see the resource files in the project list.

The resource file
must be used before the path (":" + "prefix")

ui->actionnew->setIcon(QIcon(":/img/1.jpg")); // 这样就算代码移到别的电脑也可以使用这个图片

dialog box

What standard dialog boxes does Qt provide:

  1. QColorDialog: Select color dialog.
  2. QFileDialog: Select file dialog.
  3. QFontDialog: Select font dialog box.
  4. QInputDialog: allows the user to enter a value and returns its value.
  5. QMessageBox: Message (modal) dialog box, used to display information, or ask questions, etc.
  6. QPageSetupDialog: Provides paper-related options for printers.
  7. QPrintDialog: printer configuration.
  8. QPrintPreviewDialog: print preview.
  9. QProgressDialog: displays the operation process.

1. Modal dialog box: You must respond after this dialog box pops up, otherwise you cannot click on other windows.

// 点击按钮,弹出对话框
connect(ui->actionnew, &QAction::triggered, [=](){
    
    
	// 模态对话框(不可以对其他窗口进行操作)
	QDialog dlg(this);
	dlg.resize(200, 100); // 对话框太小有警告,系统提示对话框太小可能显示不了有效信息,所以警告
	dlg.exec(); // 阻塞  必须对对话框操作完毕才放开阻塞,向下执行
	qDebug() << "模态对话框操作完毕!";});

2. Non-modal dialog box: The dialog box does not need to respond after it pops up, and you can still click on other windows.

// 点击按钮弹出对话框
connect(ui->actionnew, &QAction::triggered, [=](){
    
    
	// 非模态对话框(可以对其他窗口进行操作)
	QDialog *dlg2 = new QDialog(this); // 交给对象树释放
	dlg2->resize(200, 100);
	dlg2->show(); // 对话框独立展示后,还可以向下执行
	qDebug() << "非模态对话框执行了!" << endl;});

Note:
If you keep clicking the button to trigger the non-modal dialog box, new space will be kept.
However, the object tree is released uniformly at the end of the program,
so this object may cause memory overflow.
Solution:
Set Attribute Attribute, the allocated space will be released when the dialog box is closed.

dlg2->setAttribute(Qt::WA_DeleteOnClose);

3. Message dialog box

connect(ui->actionww, &QAction::triggered, this, [=]{
    
    
	QMessageBox::critical(this, "hello", "错误:");
});

Insert image description here

Return value: options; Parameter 1: Specify the parent class; Parameter 2: Dialog box title; Parameter 3: Displayed content; Parameter 4: Options; Parameter 5: Options associated with carriage return; Others are similar, let’s list them
:

// 信息对话框
QMessageBox::information(this, "information", "信息:");
// 提问对话框
QMessageBox::question(this, "question", "请问:");
// 警告对话框
QMessageBox::warning(this, "warning", "警告:");

The option value can be modified in the question dialog box, the default is yes|no

// 提问对话框
QMessageBox::question(this, "question", "请问:", 
							QMessageBox::Save|QMessageBox::Cancel);

The fifth parameter of the question dialog box represents the default option associated with Enter

// 提问对话框
QMessageBox::question(this, "question", "请问:", 
							QMessageBox::Save|QMessageBox::Cancel,
							QMessageBox::Cancel);

Other dialog boxes

// 颜色选择对话框,返回值是颜色的QColor类型的色域值
QColor color = QColorDialog::getColor(QColor(255,0,0,2)); // 第四参数为透明度
qDebug() << color.red() << color.green() << color.blue() << color.alpha() << endl;

// 文件对话框
QString str = QFileDialog::getOpenFileName(this, "D:/DeskTop", "(*.txt)"); // 第三参数文件过滤
qDebug() << "str: " << str << endl;// 返回值是选中文件的路径

 // 字体对话框
bool flag = true;
QFont font = QFontDialog::getFont(&flag, QFont("华文彩云", 36));
qDebug() << "字体:" << font.family().toUtf8().data() << "字号:" << font.pointSize() 
         << "是否加粗:" << font.bold() << "是否倾斜:" << font.italic() << endl; // 返回值

Interface layout

Insert image description here

Alignment
Insert image description here
Insert image description here
Insert image description here
Insert image description here

operation result
Insert image description here

If you want to align both the username and password boxes, you can drag these four components into a widget for grid layout.

Custom controls

Right-click the project—>Add New…—>select Qt—>Designer Interface Class—>OK.
Insert image description here
Insert image description here
Then give your ui interface a name.
After the creation is successful, a new ui will appear.
Insert image description here

Customize and drag the controls you want to encapsulate into a new control in the UI file you created.
Insert image description here

Make a note of what type of control you created
Insert image description here

Then click to enter the ui file created by the program by default
Insert image description here

Because the control type I created is widget
Insert image description here

Right-click the widget control -> Promote to
Insert image description here
Insert image description here

After success, you can see that the type of this control changes to a custom control type.
Insert image description here

Run to see the result, the encapsulation is successful
Insert image description here
. If you want to add functions to the custom control, just write the logic code in the custom class.

	// QSpinBox移动 QSlider跟着移动
    void (QSpinBox::* sp)(int) = &QSpinBox::valueChanged;
    connect(ui->spinBox, sp, ui->horizontalSlider, &QSlider::setValue);

    // QSlider滑动 QSpinBox数字跟着变化
    connect(ui->horizontalSlider, &QSlider::valueChanged, ui->spinBox, &QSpinBox::setValue);

Mouse events in Qt

myLabel::myLabel(QWidget* parent): QLabel(parent)
{
    
    
    // 设置鼠标追踪,不需要按下,鼠标移动就能被捕获到
    setMouseTracking(true);
}

void myLabel::enterEvent(QEvent* event){
    
    
//    qDebug() << "鼠标进入了" << endl;
}
void myLabel::leaveEvent(QEvent*){
    
    
//    qDebug() << "鼠标离开了" << endl;
}

// 鼠标移动
void myLabel::mouseMoveEvent(QMouseEvent *ev){
    
    
    QString str; // 移动检测得用buttons()函数,并用&操作
    if(ev->buttons() & Qt::LeftButton) // 右键
    str = QString("鼠标释放了  x = %1  y = %2 "
                          "globalx = %3  global = %4")
            .arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY());
    qDebug() << "鼠标移动了" << endl;
}
// 鼠标按下
void myLabel::mousePressEvent(QMouseEvent *ev){
    
    
    QString str;
    // Qt中的字符串格式化
    // x,y函数是基于控件的,globalx,globaly是基于整个电脑屏幕的
    if(ev->button() == Qt::LeftButton) // 鼠标左键
    str = QString("鼠标按下了  x = %1  y = %2 "
                          "globalx = %3  global = %4")
            .arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY());
    qDebug() << str << endl;
}
// 鼠标释放
void myLabel::mouseReleaseEvent(QMouseEvent *ev){
    
    
    QString str;
    if(ev->button() == Qt::RightButton) // 右键
    str = QString("鼠标释放了  x = %1  y = %2 "
                          "globalx = %3  global = %4")
            .arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY());
    qDebug() << str << endl;
}

timer

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    
    
    ui->setupUi(this);

    // 启动定时器
    startTimer(1000);// 参数1:间隔时间 毫秒
}
// 重写定时器事件
void Widget::timerEvent(QTimerEvent *){
    
    
    static int num = 1;
    ui->label_2->setText(QString::number(num++));
}

The return value of the startTimer() function is the unique identifier of the timer, which can be used to distinguish when there are multiple timers.

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    
    
    ui->setupUi(this);

    // 启动定时器
    id1 = startTimer(1000);// 参数1:间隔时间 毫秒
    id2 = startTimer(2000);
	// 定义成员变量来存放定时器的唯一值
}
// 重写定时器事件
void Widget::timerEvent(QTimerEvent * ev){
    
    
    if(ev->timerId() == id1){
    
    
        static int num = 1;
        ui->label_2->setText(QString::number(num++));
    }
    if(ev->timerId() == id2){
    
    
        static int num2 = 1;
        ui->label_3->setText(QString::number(num2++));
    }
}

In fact, when the startTimer function is called, a globally unique timer will be started, and the timer event will be called after the specified time interval. The event function can use the timerId function to distinguish which timer called the current event.
Call the event function repeatedly at time intervals.

Another implementation of timer (recommended)

    // 定时器的第二种实现方式
    QTimer *time = new QTimer(this);
    time->start(500); // 单位毫秒
    connect(time, &QTimer::timeout, this, [=](){
    
    
        static int num = 1;
        ui->label_4->setText(QString::number(num++));
    });

event event dispatcher

Insert image description here

Event interception (not recommended for actual use, only for learning exercises)
does not allow the event distributor to continue to distribute downwards

// event分发拦截
bool myLabel::event(QEvent *e){
    
    
    // 如果是鼠标按下事件
    if(e->type() == QEvent::MouseButtonPress){
    
    
        qDebug() << "鼠标按下事件被拦截了" << endl;
        return true;
    }
    
    // 其他事件交给父类处理
    return QLabel::event(e);
}

event filter

Insert image description here

    // 步骤1:给label安装事件过滤器
    ui->label->installEventFilter(this);
}
// 步骤2:重写事件过滤器事件
bool Widget::eventFilter(QObject* obj, QEvent* e){
    
    
    if(obj == ui->label){
    
    
        if(e->type() == QEvent::MouseButtonPress){
    
    
            qDebug() << "事件过滤:" << endl;
            QMouseEvent* ev = static_cast<QMouseEvent *>(e); // 强制类型转换,静态转换
            QString str = QString("鼠标按下了  x = %1  y = %2 "
                                  "globalx = %3  global = %4")
                    .arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY());
            qDebug() << str << endl;
            return true;
        }
    }

    return QWidget::eventFilter(obj,e);
}

drawing event

Just rewrite the paintEvent function and the system will automatically call it.

// 绘图事件
void Widget::paintEvent(QPaintEvent*){
    
    
    // 实例化画家对象  this指定的是绘图的设备
    QPainter painter(this);

    // 设置画笔的颜色
    QPen pen(QColor(255, 0, 0));
    pen.setWidth(3); // 设置笔的宽度(粗细)
    pen.setStyle(Qt::DotLine); // 设置画笔风格 (DotLine为虚线)

    // 让画家使用这个笔
    painter.setPen(pen);

    // 画刷,封闭图形填充
    QBrush brush(QColor(0,255,0));
    // 设置画刷风格
    brush.setStyle(Qt::Dense7Pattern);

    // 让画家使用刷子
    painter.setBrush(brush);

    // 画线
    painter.drawLine(QPoint(0,0), QPoint(100,100));
    // 画圆
    painter.drawEllipse(QPoint(100,100), 50, 50); // 第二参数和第三参数相当于椭圆中的a和b系数
    // 画矩形
    painter.drawRect(QRect(20,20,60,50)); // 在20,20点画长为60宽为50的矩形
    // 画文字
    painter.drawText(QRect(10, 200, 200, 50), "好好学习,天天向上");

}

Advanced drawing

// 绘图事件
void Widget::paintEvent(QPaintEvent*){
    
    
    // 实例化画家对象  this指定的是绘图的设备
	QPainter pain(this);

    pain.drawEllipse(QPoint(100,50), 50, 50);

    // 设置 抗锯齿能力,消除走样(线条更精细单效率下降)
    pain.setRenderHint(QPainter::Antialiasing);
    pain.drawEllipse(QPoint(200,50), 50, 50);

    pain.drawRect(QRect(100, 150, 60, 30));
    // 移动画家的起始位置
    pain.translate(200, 0);
    pain.drawRect(QRect(100, 150, 60, 30)); // 因为移动了画家的位置,所以这两个矩形不在同一个位置
    // 移动画家的起始位置
    pain.translate(200, 0);
    // 保存画家状态
    pain.save();
    pain.drawRect(QRect(100, 150, 60, 30));
    // 移动画家的起始位置
    pain.translate(200, 0);
    // 还原画家上一次状态
    pain.restore();
    pain.drawRect(QRect(100, 150, 60, 30)); // 因为移动了画家的位置,所以这两个矩形不在同一个位置
}

Draw resource pictures

// 绘图事件
void Widget::paintEvent(QPaintEvent*){
    
    
    // 实例化画家对象  this指定的是绘图的设备
	QPainter painter(this);
    painter.drawPixmap(posx, 100, QPixmap(":/img/2.jpg"));
}

Calling paint events manually

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    
    
    ui->setupUi(this);


    connect(ui->pushButton, &QPushButton::clicked, this, [=](){
    
    
        posx+=20;
        // 如果要手动调用绘图事件,最好用update()更新
        update();
    });
}

drawing equipment

When Qt performs drawing operations, it actually uses Qpainter to draw on QPainterDevice, and QPaintEngine is used to communicate between them.
Insert image description here

Drawing device refers to a subclass that inherits QPainterDevice. Qt provides a total of 4 such classes.

  • QPixmap: Specially optimized for the display of images on the screen.
  • QBitmap: It is a subclass of QPixmap. Its color depth is limited to 1. You can use QPixmap's isQBitmap() function to determine whether this QPixmap is a QBitmap. Only black and white.
  • QImage: Specifically optimized for pixel-level access to images. Specific pixels can be accessed.
  • QPicture: You can record and reproduce various commands of QPainter.

QPixmap
is mainly dedicated to display optimization for the platform.

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    
    
    ui->setupUi(this);
    // Pixmap绘图设备:相当于可以往磁盘上进行绘制
    QPixmap pix(300, 300);
    
    // 声明颜色:默认为黑色
    pix.fill(Qt::white);
    
    // 定义画家
    QPainter painter(&pix);
    painter.setPen(QPen(Qt::green));
    painter.drawEllipse(QPoint(150,150), 100, 100);
    
    // 保存
    pix.save("D:\\test.png");
}

No results will appear after the above code is run, but the drawing is saved to the path D:\\test.png.

Different performances of image files in Pixmap and Bitmap

void Widget::paintEvent(QPaintEvent *event){
    
    
    QPixmap pixmap(":/img/1.jpg");
    QBitmap bitmap(":/img/1.jpg");

    QPainter * pain = new QPainter(this);
    pain->drawPixmap(0, 0, pixmap); // 五颜六色
    pain->drawPixmap(0,400, bitmap); // 只显示黑白
}

QImage
operates on pixels

void Widget::paintEvent(QPaintEvent *event){
    
    
    QPainter *paint = new QPainter(this);

    // 利用QImage对像素进行修改
    QImage img;
    img.load(":/img/1.jpg");

    // 修改像素点
    for(int i = 50; i < 200; ++i){
    
    
        for(int j = 0; j < 200; ++j){
    
    
            QRgb value = qRgb(0, 255, 0);
            img.setPixel(i, j, value); // 将指定像素点修改为指定RGB颜色
        }
    }
    paint->drawImage(0,0,img);
}

Insert image description here
You can see that one lump has been changed to green.

QPictrue

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    
    
    ui->setupUi(this);

    // QPicture 绘图设备, 可以记录和重新执行绘图指令
    QPicture pic;
    QPainter paint;
    paint.begin(&pic); // 开始往pic上画
    paint.setPen(QPen(Qt::cyan));
    paint.drawEllipse(QPoint(150,150), 100, 100);
    paint.end(); // 结束绘画

    // 保存到磁盘
    pic.save("D:\\pic"); // 此时生成的文件记录了绘图指令记录,以便于后面的重新执行
}

After executing the above command, the pic file will be generated in the specified path. Now use this file to re-execute the drawing command.

void Widget::paintEvent(QPaintEvent *event){
    
    
    QPainter paint(this);
    // 重现绘图指令
    QPicture pic;
    pic.load("D:\\pic"); // 读取记录文件
    paint.drawPicture(0,0, pic);
}

Insert image description here

File reading and writing

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    
    
    ui->setupUi(this);

    // 点击按钮,弹出文件对话框

    connect(ui->pushButton, &QPushButton::clicked, [=](){
    
    
        QString path = QFileDialog::getOpenFileName(this, "打开文件", "D:\\DeskTop");
        // 将路径放入lineEdit中
        ui->lineEdit->setText(path);

        QFile file(path); // 参数:文件路径
        // 设置打开方式
        file.open(QIODevice::ReadOnly);

        // 将所有的数据读取到array中
        QByteArray array = file.readAll();
		// 读取内容放入textEdit中
        ui->textEdit->setText(array);
    });
}

operation result:
Insert image description here

By default, the utf-8 format is read. If the gbk format is read, garbled characters will appear.
Insert image description here

The following is how to read the GBK format. Use the QTextCodec class to specify the encoding format of the file.

connect(ui->pushButton, &QPushButton::clicked, [=](){
    
    
        QString path = QFileDialog::getOpenFileName(this, "打开文件", "D:/code/qtStudy");
        // 将路径放入lineEdit中
        ui->lineEdit->setText(path);

        // 编码格式类
        QTextCodec* codec = QTextCodec::codecForName("gbk");

        QFile file(path); // 参数:文件路径
        // 设置打开方式
        file.open(QIODevice::ReadOnly);

        // 将所有的数据读取到array中
        QByteArray array = file.readAll();

        // 读取内容放入textEdit中
        ui->textEdit->setText(codec->toUnicode(array));// 转换为先前指定的格式
    });

write file

// 进行写文件
file.open(QIODevice::Append); // 追加的方式打开文件
file.write("aaa");
file.close();

Specific operations on files

// QFileInfo文件信息类
QFileInfo info(path);
qDebug() << "大小:" << info.size()
         << "后缀名:" << info.suffix()
         << "文件名称:" << info.fileName()
         << "文件路径:" << info.filePath()
         << "创建日期:" << info.created().toString("yyyy/MM/dd hh:mm:ss")
         << "修改日期:" << info.lastModified().toString("yyyy-MM-dd hh:mm:ss")
         << endl;

Guess you like

Origin blog.csdn.net/Stars____/article/details/125535301