QT学习笔记(中)

news2024/11/24 8:38:10

QT学习笔记(中)

文章目录

  • QT学习笔记(中)
    • P21 消息对话框
    • P22 其他标准对话框
    • P23 登录窗口界面和布局
    • P24 控件 按钮组
    • P25 QListWidget控件
    • P26 QTreeWidget控件的使用
    • P27 tableWidget
    • P28 其他常用控件介绍
    • P30 自定义控件
    • P31 QEvent
    • P32 定时器(一)
    • P33 定时器(二)这个定时器更简单,更优
    • P34 Event事件分发器
    • P35 使用事件过滤器进行一个更高层的拦截
    • P36 绘图事件
    • P37 绘图的高级设置
    • P38 手动调用并更新绘图事件
    • P39 绘图设备
    • P40 文件的读写操作
    • P41 QFileInfo文件信息读取操作

P21 消息对话框

QMessageBox静态成员函数 创建对话框
错误、信息、提问、警告

提问 参数: 父亲 标题 提示内容 按键类型 默认关联回车的按键
返回值是Standard Button类型,利用返回值可以判断用户的输入。

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDialog>
#include<QDebug>
#include<QMessageBox>

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

    // 点击新建 弹框
    connect(ui->actionnew, &QAction::triggered, [=](){
       // 消息对话框
//       QMessageBox::critical(this, "critical", "错误");
       // 错误对话框
//       QMessageBox::information(this, "info", "信息");
       // 提问 参数: 父亲 标题 提示内容 按键类型 默认关联回车的按键
       QMessageBox::StandardButton sbtn = QMessageBox::question(this, "ques", "提问", QMessageBox::Save|QMessageBox::Cancel, QMessageBox::Cancel);

       if (sbtn == QMessageBox::Save){
           qDebug() << "点击了保存按钮";
       }else{
           qDebug() << "点击了取消按钮";
       }

       // 警告
       QMessageBox::warning(this, "warn", "警告");

    });

}

MainWindow::~MainWindow()
{
    delete ui;
}


在这里插入图片描述

P22 其他标准对话框

  1. 颜色对话框:QColorDialog::getColor
  2. 文件对话框:QFileDialog::getOpenFileName() 参数:父亲,标题,默认路径,过滤。
  3. 字体对话框:QFontDialog::getFont()
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDialog>
#include<QDebug>
#include<QMessageBox>
#include<QColorDialog>
#include<QFileDialog>
#include<QFontDialog>

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

    // 点击新建 弹框
    connect(ui->actionnew, &QAction::triggered, [=](){

//        QColor color = QColorDialog::getColor(QColor(255, 0, 0));
//        qDebug() << "r=" << color.red() << " g=" << color.green() << " b=" << color.blue();

        // 文件对话框  参数: 父亲 标题 默认打卡路径 过滤文件的格式
//        Qstring str = QFileDialog::getOpenFileName(this, "打开", "D:/", "(*.txt)");
//        qDebug() << str;

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

    });


}

MainWindow::~MainWindow()
{
    delete ui;
}


P23 登录窗口界面和布局

在这里插入图片描述

  1. 实现登录窗口
  2. 利用布局方式 给窗口进行美化
  3. 选取widget 进行布局、水平布局、垂直布局、栅格布局。
  4. 给用户名、密码、登录、退出按钮进行布局
  5. 默认窗口和控件之间有9px的间隙,可以调整layoutLeftMargin
  6. 利用弹簧进行布局。
    请添加图片描述

P24 控件 按钮组

  1. QPushButton 常用按钮
  2. QToolButton 工具按钮,用于显示图片,如图想显示文字,
    2.1 修改风格:toolButtonStyle
    2.2 凸起风格 autoRaise
  3. redioButton 单选按钮。设置默认 ui->rBtnMan->setCheck(true)
  4. checkbox多选按钮,监控状态 2 选中 1 半选 0 未选中

在这里插入图片描述
代码部分:

#include "widget.h"
#include "ui_widget.h"
#include <QDebug>

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

    // 默认是选中 男
    ui->rbtnMan->setChecked(true);


    connect(ui->rbtnWoman, &QRadioButton::clicked, this, [=](){
        qDebug() << "选中了女";
    });
    // 多选按钮 2是选中 0是没有选中
    connect(ui->cbox, &QCheckBox::stateChanged, this, [=](int state){
        qDebug() <<state;
    });
}

Widget::~Widget()
{
    delete ui;
}


P25 QListWidget控件

#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
#include <QListWidget>

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

    // 默认是选中 男
    ui->rbtnMan->setChecked(true);


    connect(ui->rbtnWoman, &QRadioButton::clicked, this, [=](){
        qDebug() << "选中了女";
    });
    // 多选按钮 2是选中 0是没有选中
    connect(ui->cbox, &QCheckBox::stateChanged, this, [=](int state){
        qDebug() <<state;
    });

    // listWidget
    QListWidgetItem *item = new QListWidgetItem("锄禾日当午");
    // 放入控件中
//    ui->listWidget->addItem(item);
    // 居中对齐
//    item->setTextAlignment(Qt::AlignHCenter);
    // QStringList QList<QString>
    QStringList list;
    list << "锄禾日当午" << "汗滴禾下土" << "谁知盘中餐" << "粒粒皆辛苦";
    ui->listWidget->addItems(list);

}

Widget::~Widget()
{
    delete ui;
}


在这里插入图片描述

P26 QTreeWidget控件的使用

  1. 标题的创建 ui->treeWidget->setHeaderLabels(QStringList()<<“英雄”<<“英雄介绍”);
  2. 根节点的创建和加入
    ui->treeWidget->addTopLevelItems(QList<QTreeWidgetItem*>()<<liItem<<minItem<<zhiItem);
  3. 追加子节点 liItem->addChild(l1);
    代码如下:
#include "widget.h"
#include "ui_widget.h"
#include <QList>

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

    ui->treeWidget->setHeaderLabels(QStringList()<<"英雄"<<"英雄介绍");
    QTreeWidgetItem *liItem = new QTreeWidgetItem(QStringList()<<"力量");
    QTreeWidgetItem *minItem = new QTreeWidgetItem(QStringList()<<"敏捷");
    QTreeWidgetItem *zhiItem = new QTreeWidgetItem(QStringList()<<"智力");

    // 加载顶层节点
    ui->treeWidget->addTopLevelItems(QList<QTreeWidgetItem*>()<<liItem<<minItem<<zhiItem);

    // 追加子节点
    QStringList heroL1;
    heroL1 << "刚被猪" << "前排泰克";
    QTreeWidgetItem *l1 = new QTreeWidgetItem(heroL1);
    liItem->addChild(l1);

}

Widget::~Widget()
{
    delete ui;
}


在这里插入图片描述

P27 tableWidget

#include "widget.h"
#include "ui_widget.h"


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

    ui->tableWidget->setColumnCount(3);

    ui->tableWidget->setHorizontalHeaderLabels(QStringList()<< "角色"<< "性别"<< "年龄");

    ui->tableWidget->setRowCount(3);

    QStringList nameList;
    nameList << "张飞" << "关羽" << "刘备";

    QList<QString> sexList;
    sexList << "男" << "女" << "男";
    for (int i =0; i<3; ++i){

        ui->tableWidget->setItem(i, 0, new QTableWidgetItem(nameList[i]));
        ui->tableWidget->setItem(i, 1, new QTableWidgetItem(sexList.at(i)));
        ui->tableWidget->setItem(i, 2, new QTableWidgetItem(QTableWidgetItem(QString::number(18+i))));
    }


}

Widget::~Widget()
{
    delete ui;

}


在这里插入图片描述

P28 其他常用控件介绍

#include "widget.h"
#include "ui_widget.h"

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

    ui->stackedWidget->setCurrentIndex(1);

    connect(ui->pbtn, &QPushButton::clicked, [=](){
        ui->stackedWidget->setCurrentIndex(0);
    });

    connect(ui->rbtn, &QPushButton::clicked, [=](){
        ui->stackedWidget->setCurrentIndex(1);
    });

    ui->pbtn->setIcon(QIcon(":/Image/qq.png"));


    ui->comboBox->addItems(QStringList()<< "奔驰" << "宝马" << "拖拉机");

    connect(ui->vbtn, &QPushButton::clicked, [=](){
//        ui->comboBox->setCurrentIndex(2);
        ui->comboBox->setCurrentText("拖拉机");
    });

    ui->label->setPixmap(QPixmap(":/Image/qq.png"));


}

Widget::~Widget()
{
    delete ui;
}


在这里插入图片描述

P30 自定义控件

新建: 文件->newfile->Qt->Qt设计界面类
然后通过ui界面进行相关的设计。这里设置了一个QSlider和QSpinBox组合,数值改变时候进行联动。
在这里插入图片描述
在form.cpp添加下面的代码,定义两个控件之间的类和槽的连接,就可以实现联动。

#include "form.h"
#include "ui_form.h"

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

    connect(ui->spinBox, &QSpinBox::valueChanged, ui->horizontalSlider, &QSlider::setValue);
    connect(ui->horizontalSlider, &QSlider::valueChanged, ui->spinBox, &QSpinBox::setValue);


}

Form::~Form()
{
    delete ui;
}

回到widget.ui界面中,拖拽一个widget出来,右键->提升为。输入刚刚新建的类名,就可以提升为自定义的控件。
在这里插入图片描述
定义自定义控件对外接口,在form.hpp,和form.cpp实现接口函数,这里就用两个接口,getValue,setValue。

#include "form.h"
#include "ui_form.h"

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

    connect(ui->spinBox, &QSpinBox::valueChanged, ui->horizontalSlider, &QSlider::setValue);
    connect(ui->horizontalSlider, &QSlider::valueChanged, ui->spinBox, &QSpinBox::setValue);


}

Form::~Form()
{
    delete ui;
}


void Form::setValue(int num){
    ui->horizontalSlider->setValue(num);
    ui->spinBox->setValue(num);
}

int Form::getValue(){
    return ui->horizontalSlider->value();
}

最后在widget.ui拖拽两个按钮,然后连接这个widget的槽函数就可以了。

#include "widget.h"
#include "ui_widget.h"
#include <QDebug>

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


    connect(ui->gbtn, &QPushButton::clicked, this, [=](){
        int num = ui->widget->getValue();
        qDebug() << "当前值是: " << num;
    });

    connect(ui->sbtn, &QPushButton::clicked, this, [=](){
        ui->widget->setValue(50);
    });

}

Widget::~Widget()
{
    delete ui;
}


P31 QEvent

qt中有好多事件,这里以鼠标事件为例,新建一个QLabel的控件。
在这里插入图片描述
可以再mylabel.h, mylabel.cpp中设置事件的处理方法
关于QLabel的鼠标事件,我们可以直接看帮助文档,下面是QLabel的帮助文档以及相关的截图。
在这里插入图片描述

mylabel.h,这里定义了4个鼠标事件,

#ifndef MYLABEL_H
#define MYLABEL_H

#include <QLabel>
#include<QPointingDevice>

class myLabel : public QLabel
{
    Q_OBJECT
public:
    explicit myLabel(QWidget *parent = nullptr);


    void leaveEvent(QEvent *event);


    void mouseMoveEvent(QMouseEvent *ev);
    void mousePressEvent(QMouseEvent *ev);
    void mouseReleaseEvent(QMouseEvent *ev);



signals:

};

#endif // MYLABEL_H

mylabel.cpp 事件的实现。

#include "mylabel.h"
#include <QDebug>
#include <QMouseEvent>

myLabel::myLabel(QWidget *parent)
    : QLabel{parent}
{
    setMouseTracking(true);
}




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



void myLabel::mousePressEvent(QMouseEvent *ev){
    qDebug()<< "鼠标按下了";
    // 左键按下才捕获
    if (ev->button()==Qt::LeftButton){
        QString str = QString("x=%1, y=%2, globalx=%3, globaly=%4").arg(ev->position().x()).arg(ev->position().y()).arg(ev->globalPos().x()).arg(ev->globalY());
        qDebug()<< str;
    }
}

void myLabel::mouseReleaseEvent(QMouseEvent *ev){
    qDebug()<< "鼠标释放了";
}


void myLabel::mouseMoveEvent(QMouseEvent *ev){
    qDebug()<< "鼠标移动了";
    QString str = QString("x=%1, y=%2, globalx=%3, globaly=%4").arg(ev->position().x()).arg(ev->position().y()).arg(ev->globalPos().x()).arg(ev->globalY());
    qDebug()<< str;

//    if (ev->buttons() & Qt::LeftButton){
//        QString str = QString("x=%1, y=%2, globalx=%3, globaly=%4").arg(ev->position().x()).arg(ev->position().y()).arg(ev->globalPos().x()).arg(ev->globalY());
//        qDebug()<< str;
//    }
}

运行后自动捕获鼠标事件,并且输出当前光标的位置了。
在这里插入图片描述

P32 定时器(一)

使用startTimer去创建定时器。
核心:在widget.h先重写timerEvent,然后通过startTimer去启动定时器,startTimer返回定时器的编号作为标识符。
widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

    void timerEvent(QTimerEvent *);
    int timer_id1;
    int timer_id2;

private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include <QTimer>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    // 1000ms 计时一次
    timer_id1 = startTimer(1000);
    timer_id2 = startTimer(2000);

}

Widget::~Widget()
{
    delete ui;
}



void Widget::timerEvent(QTimerEvent *ev){
    static int i = 0;
    static int j = 0;

    if (ev->timerId() == timer_id1){
        ui->label_2->setText(QString::number(++i));
    }

    if (ev->timerId() == timer_id2){
        ui->label_3->setText(QString::number(++j));
    }
}

在这里插入图片描述

P33 定时器(二)这个定时器更简单,更优

使用QTimer去创建一个定时器类,然后每隔一定时间触发一个信号,然后调用槽函数。

#include "widget.h"
#include "ui_widget.h"
#include <QTimer>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    // 1000ms 计时一次
    timer_id1 = startTimer(1000);
    timer_id2 = startTimer(2000);

    QTimer *timer = new QTimer(this);

    timer->start(500);
    connect(timer, &QTimer::timeout, this, [=](){
        static int num = 1;
        ui->label_4->setNum(++num);
    });
    // 控制定时器开始
    connect(ui->pushButton, &QPushButton::clicked, this, [=](){
        timer->start(500);
    });
    // 控制定时器停止
    connect(ui->pushButton_2, &QPushButton::clicked, this, [=](){
        timer->stop();
    });



}

Widget::~Widget()
{
    delete ui;
}



void Widget::timerEvent(QTimerEvent *ev){
    static int i = 0;
    static int j = 0;

    if (ev->timerId() == timer_id1){
        ui->label_2->setText(QString::number(++i));
    }

    if (ev->timerId() == timer_id2){
        ui->label_3->setText(QString::number(++j));
    }
}

在这里插入图片描述

P34 Event事件分发器

在这里插入图片描述1. 用途,用于事件的分发
2. 可以做事件的拦截
3. bool event(QEvent *e)
4. 返回值如果是true代表用户已经处理了这个时间,不再向下分发
5. e->type() == 鼠标按下

需要在mylabel.h添加这个函数的定义,这里由于篇幅问题就不贴出来了。下面是mylabel.cpp里面函数的实现。

#include "mylabel.h"
#include <QDebug>
#include <QMouseEvent>

myLabel::myLabel(QWidget *parent)
    : QLabel{parent}
{
    setMouseTracking(true);
}




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



void myLabel::mousePressEvent(QMouseEvent *ev){
    qDebug()<< "鼠标按下了";
    // 左键按下才捕获
    if (ev->button()==Qt::LeftButton){
        QString str = QString("x=%1, y=%2, globalx=%3, globaly=%4").arg(ev->position().x()).arg(ev->position().y()).arg(ev->globalPos().x()).arg(ev->globalY());
        qDebug()<< str;
    }
}

void myLabel::mouseReleaseEvent(QMouseEvent *ev){
    qDebug()<< "鼠标释放了";
}


void myLabel::mouseMoveEvent(QMouseEvent *ev){
    qDebug()<< "鼠标移动了";
    QString str = QString("x=%1, y=%2, globalx=%3, globaly=%4").arg(ev->position().x()).arg(ev->position().y()).arg(ev->globalPos().x()).arg(ev->globalY());
    qDebug()<< str;
    // 判断是左键按下才执行
//    if (ev->buttons() & Qt::LeftButton){
//        QString str = QString("x=%1, y=%2, globalx=%3, globaly=%4").arg(ev->position().x()).arg(ev->position().y()).arg(ev->globalPos().x()).arg(ev->globalY());
//        qDebug()<< str;
//    }
}

bool myLabel::event(QEvent *e){
    if (e->type()==QEvent::MouseButtonPress){
        QMouseEvent *ev = static_cast<QMouseEvent*>(e);
        QString str = QString("QEvent中进行拦截。 鼠标按下了。x=%1, y=%2, globalx=%3, globaly=%4").arg(ev->position().x()).arg(ev->position().y()).arg(ev->globalPos().x()).arg(ev->globalY());
        qDebug()<< str;
        return true; // 返回true
    }
    return QLabel::event(e);
}

在这里插入图片描述
上面运行结果可以看到,鼠标按下QLabel时候,event方法已经进行了拦截。从而没有调用mousePressEvent方法。

P35 使用事件过滤器进行一个更高层的拦截

下图可以看到eventfilter事件过滤器在
在这里插入图片描述
具体实现步骤如下:

注意,我们是在最大的窗口那里实现的,并非我们的控件的文件!!!
即,在widget.cpp中实现

  1. 在widget.cpp 中安装事件过滤器:
    // 安装事件过滤器
    ui->label->installEventFilter(this);
  1. 在widget.h定义eventFilter(QObject*, QEvent*)函数
public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

    bool eventFilter(QObject*, QEvent*);
  1. 在widget.cpp实现eventFilter
bool Widget::eventFilter(QObject *obj, QEvent *e){
    if (obj==ui->label){
        if (e->type()==QEvent::MouseButtonPress){
            QMouseEvent *ev = static_cast<QMouseEvent*>(e);
            QString str = QString("eventFilter中进行拦截。 鼠标按下了。x=%1, y=%2, globalx=%3, globaly=%4").arg(ev->position().x()).arg(ev->position().y()).arg(ev->globalPos().x()).arg(ev->globalY());
            qDebug()<< str;
            return true; // 返回true
        }
    }
    return QWidget::eventFilter(obj, e);
}

在这里插入图片描述
上面结果可以看到,eventFilter在最上层进行了拦截,就没有去运行bool myLabel::event(QEvent *e)的代码了,更不用说下面这上个myLabel中从QLabel继承过来的具体事件。

    void mouseMoveEvent(QMouseEvent *ev);
    void mousePressEvent(QMouseEvent *ev);
    void mouseReleaseEvent(QMouseEvent *ev);

P36 绘图事件

使用QPainter进行绘图操作。设置pen,brush等。

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include <QPainter>

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

Widget::~Widget()
{
    delete ui;
}

void Widget::paintEvent(QPaintEvent *){
    // 实例化画家对象
    QPainter painter(this);
    // 设置笔的颜色
    QPen pen(QColor(255, 0, 0));
    // 设置画笔宽度
    pen.setWidth(3);
    // 设置画笔风格
    pen.setStyle(Qt::DashLine);
    // 让画家使用画笔
    painter.setPen(pen);

    // 设置画刷
    QBrush brush(Qt::green);
    brush.setStyle(Qt::Dense7Pattern);
    // 让画家使用画刷
    painter.setBrush(brush);

    // 画线
    painter.drawLine(QPoint(0, 0), QPoint(100, 100));
    // 画圆
    painter.drawEllipse(QPoint(100, 100), 50, 50);
    // 画矩形
    painter.drawRect(QRect(20, 20, 50, 50));
    // 画文字
    painter.drawText(QRect(10, 200, 100, 50), "好好学习,天天向上");

}


在这里插入图片描述

P37 绘图的高级设置

#include "widget.h"
#include "ui_widget.h"
#include <QPainter>

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

Widget::~Widget()
{
    delete ui;
}

void Widget::paintEvent(QPaintEvent *){
    // 实例化画家对象
    QPainter painter(this);
    // 设置笔的颜色
    QPen pen(Qt::blue);
    pen.setWidth(2);
    painter.setPen(pen);

    painter.drawEllipse(QPoint(100, 50), 50, 50);
    // 抗锯齿
    painter.setRenderHint(QPainter::Antialiasing);
    painter.drawEllipse(QPoint(200, 50), 50, 50);

    painter.drawRect(QRect(50, 150, 50, 50));
    // 移动画家的原点 x方向移动100, y 方向移动 0
    painter.translate(QPoint(100, 0));
    // 保存画家的相对位置
    painter.save();
    painter.drawRect(QRect(50, 150, 50, 50));

    painter.translate(QPoint(100, 0));
    // 恢复到上一次保存的位置
    painter.restore();

    painter.drawRect(QRect(50, 150, 50, 50));
}

在这里插入图片描述

P38 手动调用并更新绘图事件

使用QPainter来绘图,并手动更新绘图,下面代码实现点击QPushButton图片向右移动20px,或者定时触发自动右移20px的功能。

#include "widget.h"
#include "ui_widget.h"
#include <QPainter>
#include <QTimer>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    // 点击按钮移动20px
    connect(ui->pushButton, &QPushButton::clicked, [=](){
        Xpos += 20;
        update();
    });
    // 定时移动20px
    QTimer *timer = new QTimer(this);
    timer->start(500);
    connect(timer, &QTimer::timeout, [=](){
        Xpos += 20;
        update();
    });

}

Widget::~Widget()
{
    delete ui;
}


void Widget::paintEvent(QPaintEvent *){
    QPainter painter(this);
    painter.drawPixmap(Xpos, 50, QPixmap(":/Image/qq.png"));

    if (Xpos > this->width()){
        Xpos = 0;
    }

}


在这里插入图片描述

P39 绘图设备

QPaintDevice分为QPixmap,Qimage以及QPicture,QPainter可以再设备上面画画,不同设备的特性是略有不一样的。

QPixmap:
对不同平台的显示进行优化,但支持像素级别的访问。下面图片是QPainter在QPixmap上面进行画画并且保存后得到的结果。
请添加图片描述

Qimage:
可以支持像素级别访问。下面实例通过for循环修改了一部分的像素。
请添加图片描述

QPicture:
用于记录和保存QPainter画家的操作方法,然后可以载入方法进行画画。保存的路径文件名为zt,是不能打开的,只能通过QPicture的load方法访问读取。
请添加图片描述
上面实例的代码统一基础在下面,注意的是,绘图时间paintEvent需要在widget.h头文件上面去申明。

#include "widget.h"
#include "ui_widget.h"
#include <QPixmap>
#include <QPainter>
#include <QImage>
#include <QPicture>



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

    // Pixmap绘图设备
    QPixmap pix(300, 300);
    // 定义画家
    QPainter painter(&pix);
    // 填充白色
    pix.fill(Qt::white);
    painter.setPen(QPen(Qt::green));
    painter.drawEllipse(QPoint(150, 150), 100, 100);
    // 保存
    pix.save("D:/pix.png");

    // QImage绘图设备 可以对像素进行访问
    QImage img(300, 300, QImage::Format_RGB32);
    img.fill(Qt::white);

    QPainter painter2(&img);
    painter2.setPen(QPen(Qt::blue));
    painter2.drawEllipse(QPoint(150, 150), 100, 100);
    img.save("D:/img.png");

    // QPicture 绘图设备
    QPicture pic;
    QPainter painter3;
    painter3.begin(&pic);
    painter3.setPen(QPen(Qt::green));

    QBrush brush(Qt::red);
    brush.setStyle(Qt::RadialGradientPattern);
    painter3.setBrush(brush);
    painter3.drawEllipse(QPoint(100, 100), 100, 100);
    // 退出指令不能少,否则保存的路径是空的
    painter3.end();
    // 保存一个绘图指令文件,里面有画家的绘图方法
    pic.save("D:/picture.zt");

}

Widget::~Widget()
{
    delete ui;
}


// 绘图事件
void Widget::paintEvent(QPaintEvent *){
    QPainter painter(this);
    QImage img;

    img.load(":/Image/clock.png");

    QRgb rgb = qRgb(255, 0, 255);
    for (int i=0; i<100; ++i){
        for (int j=0; j<100; ++j){
            img.setPixel(i, j, rgb);
        }
    }
    painter.drawImage(0, 0, img);

    QPainter painter3(this);
    QPicture pic;
    pic.load("D:/picture.zt");
    painter3.drawPicture(0, 0, pic);

}


P40 文件的读写操作

使用QFile进行文件的读写操作

  1. QFile fIle(path 文件路径)
  2. 全部读取 file.readAll()
  3. 编码问题,使用QTextCodec来进行转码操作
  4. 写 filel.write(char *)
#include "widget.h"
#include "ui_widget.h"
#include <QFileDialog>
#include <QFile>
// 需要在 pro文件加入 QT += core5compat
#include <QTextCodec>

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

    connect(ui->pushButton, &QPushButton::clicked, [=](){
        QString path = QFileDialog::getOpenFileName(this, "打开文件", "D:\\project\\QT\\day03\\05_QFile", "*.txt");
        ui->lineEdit->setText(path);
        QFile file(path);

        file.open(QIODeviceBase::ReadOnly);
        // 一次读取
//        QByteArray array =  file.readAll();

        // 按行来读取
        QByteArray array;
        while(!file.atEnd()){
            array += file.readLine();
        }
        ui->textEdit->setText(array);

        // GBK
//        QTextCodec *codec = QTextCodec::codecForName("gbk");
//        ui->textEdit->setText(codec->toUnicode(array));
        file.close();

        // 写文件
        file.open(QIODeviceBase::Append);
        file.write("\n新添加的内容");
        file.close();

    });


}

Widget::~Widget()
{
    delete ui;
}


在这里插入图片描述

P41 QFileInfo文件信息读取操作

读取文件的相关信息并且弹窗来打印

#include "widget.h"
#include "ui_widget.h"
#include <QFileDialog>
#include <QFile>
// 需要在 pro文件加入 QT += core5compat
#include <QTextCodec>
#include <QFileInfo>
#include <QDebug>
#include <QMessageBox>
#include <QDateTime>

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

    connect(ui->pushButton, &QPushButton::clicked, [=](){
        QString path = QFileDialog::getOpenFileName(this, "打开文件", "D:\\project\\QT\\day03\\05_QFile", "*.txt");
        ui->lineEdit->setText(path);
        QFile file(path);

        file.open(QIODeviceBase::ReadOnly);
        // 一次读取
//        QByteArray array =  file.readAll();

        // 按行来读取
        QByteArray array;
        while(!file.atEnd()){
            array += file.readLine();
        }
        ui->textEdit->setText(array);

        // GBK
//        QTextCodec *codec = QTextCodec::codecForName("gbk");
//        ui->textEdit->setText(codec->toUnicode(array));
        file.close();

        // 写文件
        file.open(QIODeviceBase::Append);
//        file.write("\n新添加的内容");
        file.close();

        QFileInfo info(path);
        QString str = QString("大小=%1, 后缀名=%2, 文件名称=%3, 文件路径=%4").arg(info.size()).arg(info.suffix()).arg(info.fileName()).arg(info.filePath());
        QMessageBox::information(this, "文件信息", str);

        QDateTime time = info.birthTime();
        QMessageBox::information(this, "创建日期", time.toString("yyyy-MM-dd hh:mm:ss"));

    });


}

Widget::~Widget()
{
    delete ui;
}


请添加图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/91334.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

PyQt5 QtChart-折线图

PyQt5 QtChart-QLineSeries 折线图QLineSeriesQLineSeries QLineSeries类将数据序列显示为折线图&#xff0c;其核心代码&#xff1a; lineSeries QLineSeries() lineSeries.append(1, 3) lineSeries.append(5, 8) … chart.addSeries(lineSeries) 常用方法&#xff1a; set…

【linux】容器之代码自动发布-docker

一、分析 旧&#xff1a; 代码发布环境提前准备&#xff0c;以主机为颗粒度静态 新&#xff1a; 代码发布环境 多套&#xff0c;以容器为颗粒度编译 二、业务发布逻辑设计图 三、工具使用流程图 工具 gitgitlabjenkinstomcatmavenharbordocker 流程图 四、主机规划 五…

​智能化加速,「中国供应商」如何跨越规模化周期|高工观察

在过去的十年时间里&#xff0c;中国在智能电动汽车行业下了巨大的「赌注」&#xff0c;整个行业及其背后快速成长的本地化产业链生态系统成为新一轮汽车产业增长的新引擎。 与此同时&#xff0c;电动化、智能化技术的国产化突围&#xff0c;也让整个中国本土汽车产业链获得了…

SuperMap GIS的TIN地形数据处理QA

目录 一、TIN地形数据简介 二、TIN地形数据格式 三、TIN地形数据处理 3.1 导入数据集 3.2 生成TIN地形缓存 3.3 IDesktop场景加载TIN地形 3.4 发布服务 3.5 WebGL场景加载 3.5.1 viewer初始化加载 3.5.2 scene.open加载 四、可能遇到的报错及解决方案 问题一&#xff1a;多个TI…

蓝海创意云×可米酷 || “360VR全景直播解决方案”亮相企业产品发布会

12月8日&#xff0c;可米酷2023新品发布会重磅召开&#xff0c;蓝海创意云为可米酷提供了前沿技术支持&#xff0c;助力整场活动实现了360全景VR在线直播&#xff0c;为企业线下发布会直播活动提供借鉴。 发布会现场采用了全新的虚拟现实技术VR视频全景直播方式&#xff0c;全国…

Spring 中 PageHelper 不生效问题

使用这个插件时要注意版本的问题&#xff0c;不同的版本可能 PageHelper 不会生效 springboot 导入的 pagehelper 包 <dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper-spring-boot-starter</artifactId><vers…

java+mysql 基于ssm的校园二手交易系统

现如今,校园二手交易系统是商业贸易中的一条非常重要的道路,可以把其从传统的实体模式中解放中来,网上购物可以为消费者提供巨大的便利。通过校园二手交易系统这个平台,可以使用户足不出户就可以了解现今的流行趋势和丰富的商品信息,为用户提供了极大的方便,校园二手交易系统的…

技术分享 | 跨平台API对接(Java)

本章介绍基于 Jenkins API 调用的跨平台 API 对接。 基于Jenkins实现跨平台API对接 Jenkins 提供了远程访问应用编程接口&#xff08;Remote Access API&#xff09;&#xff0c;能够通过 Http 协议远程调用相关命令操作 Jenkins 进行 Jenkins 视图、任务、插件、构建信息、任…

vue3 安装使用scss

1、安装相关依赖 node-sass css-loader style-loader sass-loader 2、声明 lang"scss" 或者 scss文件中就可以直接使用 3、重点&#xff1a;安装依赖的过程中出现的各种问题 3.1、安装node-sass 报错 如果没有安装python,就去下个安装包装一下记得配置环境变量…

世界杯小吐槽

冷门 在看这次世界杯的时候&#xff0c;心里真的是一上一下&#xff0c;今年的冷门太多了&#xff01; 如&#xff1a; 阿根延 VS 沙特阿拉伯 阿根延输了&#xff08;我想可能是阿拉伯的战术比较新吧!&#xff09;那场比赛之后&#xff0c;阿拉伯还全国放假一天。到现在&#…

1.浮动 float

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 1.4什么是浮动 float属性用于创建浮动框&#xff0c;将其移动到右边&#xff0c;直到左边缘或右边缘触及包含块或另一个浮动框的边缘。 1、语法&#xff1a; <style> …

2023年pmp的考试时间是什么时候?

PMP 考试一年是有四次考试&#xff0c;分别是 3 月、6月、9月、12月&#xff0c;不出意外的话就是这几个月了&#xff0c;提前 2 个月开始报名&#xff0c;但还是要关注PMI/基金会官网的信息&#xff0c;以官网的消息为准。 一、报考条件 报考条件其实挺简单的&#xff0c;最核…

MFC 错误 error C2504: “CDialogEx”: 未定义基类-报错解决

错误&#xff1a; 在MFC文件中添加资源窗口&#xff0c;后添加新类&#xff0c;随后在.h头文件中出现 CDialogEx C class 未定义基类错误。 原因&#xff1a; 首先&#xff0c;下图这个framework.h非常关键&#xff0c;它在pch.h中也有定义&#xff0c;所以下图这个framework.h…

编译原理实验三

编译原理实验三 问题1: cpp与.ll的对应 请描述你的cpp代码片段和.ll的每个BasicBlock的对应关系。描述中请附上两者代码。 assign 对应的.ll代码如下&#xff1a; define i32 main() #0 {%1 alloca [10 x i32] ;int a[10]%2 getelementptr inbounds [10 x i32], [10 …

用“博弈论”看什么是高质量的代币设计?

在每个领域&#xff0c;都有国王&#xff0c;皇后&#xff0c;小兵和其他玩家。它们决定了该行业赖以生存的质量和标准。在同一领域&#xff0c;必然有赢家和输家。对于加密货币和代币经济来说&#xff0c;情况也是如此。本文的重点是代币经济的博弈论。它涉及游戏本身、谁在玩…

【大数据技术Hadoop+Spark】HDFS概念、架构、原理、优缺点讲解(超详细必看)

一、相关基本概念 文件系统。文件系统是操作系统提供的用于解决“如何在磁盘上组织文件”的一系列方法和数据结构。 分布式文件系统。分布式文件系统是指利用多台计算机协同作用解决单台计算机所不能解决的存储问题的文件系统。如单机负载高、数据不安全等问题。 HDFS。英文…

freeswitch的distributor模块

概述 freeswitch 是一款简单好用的VOIP开源软交换平台。 当呼叫是同一个入中继&#xff0c;但是有多条出中继时&#xff0c;需要对出中继做负载均衡&#xff0c;mod_distributor模块可以完成对应的配置和路由。 mod_distributor是一个轻量级的线路分发模块&#xff0c;配置简…

【Redis技术探索】「底层架构原理」探索分析服务核心数据结构介绍和案例

Redis常用存储类型 Redis底层提供了5种数据结构&#xff1a;字符串、哈希、列表、集合、有序集合 下图非常形象的表示了数据结构&#xff1a; 字符串String 常用命令 EX seconds&#xff1a;设置失效时长&#xff0c;单位秒PX milliseconds&#xff1a;设置失效时长&#x…

过滤器工厂详解

内置过滤器 1 AddRequestHeader GatewayFilter Factory 添加请求头 2 AddRequestParameter GatewayFilter Factory 3 AddResponseHeader GatewayFilter Factory 4 DedupeResponseHeader GatewayFilter Factory 5 Hystrix GatewayFilter Factory 6 FallbackHeaders GatewayFil…

答对这 9 题你就超越了 83.3% 的图数据库 NebulaGraph 用户

熟悉 NebulaGraph 社区的小伙伴可能都知道一个技能认证叫做&#xff1a;NGCP&#xff0c;全称 NebulaGraph Certified Professional。用户在考试认证期间在 1 个小时内回答 100 道题目&#xff0c;并获得 60 分&#xff0c;便是 NebulaGraph 认证过的 NGCP 用户。NGCP 用户除了…