QT5入门学习(一)

DAY01

添加按钮之前先包含头文件,在widget.h中#include,第一个字母都是Q。继续在private:下面添加如下代码。

private:
    QPushButton b1;//可以直接使用
    QPushButton *b2;//不能直接使用。空指针,需要实际的内存。
    
    //按钮进行初始化,实例化,实例化的2种方式。
    b2 = new QPushButton("hello,qt");
    //b2->setText("hello,qt");
    b2->show();

界面如图所示,未达到预期效果,因为窗口2没有依附窗口1。
QT5入门学习(一)_第1张图片
如果窗口需要依附另外一个窗口,需要给该窗口指定一个父类。让他依附于谁就把窗口类传给他。

b2 = new QPushButton("hello,qt",this);

用第一种方式创建按钮,没有用.show();也出现了
QT5入门学习(一)_第2张图片父窗口显示的时候,子窗口也会随之显示。如果有100个窗口还要show100次,但是指定了this这个父类,子类就不需要show了。但是出现了hello qt被覆盖了,于是我们要改变按钮的位置。得出结论,窗口的坐标系原点在左上角,X轴向右递增,Y轴向下递增。
QT5入门学习(一)_第3张图片
QT中的对象树。析构顺序和构造的顺序相反。QT的内存回收机制:1、使用的类是直接或者间接从QObject的派生。2、类在创建对象的时候指定父对象,在析构的时候首先析构子类对象。
QT5入门学习(一)_第4张图片添加新文件不改变参数类型只改变父类对象。并且在头文件中添加析构函数。
QT5入门学习(一)_第5张图片
析构过程:在widget.h中创建对象,之后运行项目。
在这里插入图片描述
运行结果如图所示。
QT5入门学习(一)_第6张图片关闭UI界面的时候,默认被释放。
在这里插入图片描述

函数的使用

对于类来说,直接按下F1进入帮助文档,对于类的函数来说,指定完成参数之后按下F1进入帮助文档。
在这里插入图片描述
QT5入门学习(一)_第7张图片
设置窗口的标题,在widget下用this指针指向本作用域。也可以在main函数中对窗口标题进行设置,直接用到w.resize(),w.setWindowTitle()函数。

//设置窗口的标题
this->setWindowTitle("环境监测系统");

设置固定的窗口大小。

 //设置固定的宽度和高度
 this->setFixedSize(200,300);

设置窗口图标

  //设置窗口图标
    this->setWindowIcon(QIcon("D:\\1.png"));

标准的信号和槽

点击一下b1按钮关闭对象。函数剖析:
信号和槽都是函数,1、信号只有函数声明没有函数定义。
2、槽函数需要声明也需要定义。只是个回调函数。

	//需求 b1 关闭窗口
    //connect (b1,发出信号,this,处理槽函数);
    connect (&b1,&QPushButton::clicked,this,&Widget::close);

更换需求:当按下b1的时候b2的显示内容改变。
槽函数的特性:
/*自定义槽函数
*1、槽函数在Qt5中可以任意成员函数,全局函数,静态函数 lambda表达式(隐式函数)
*2、槽函数需要与信号对应(返回值和参数)
*3、信号是没有返回值的,槽函数的返回值是:void
*4、void mysig(int,double,qstring);
* void mtslot(int double qstring);
*5、槽函数的信号是为了接收信号传过来的数据。
*6、槽函数的参数是不能够大于信号的参数个数,可以少于信号的参数个数。
*7、槽函数可以重载。
*/

功能实现:在widget中添加声明,之后再在widget.cpp中完成函数实现。

自定义信号

更换需求:仅仅显示一个界面。
重新添加一个subwidget.cpp和subwidget.h。在头文集中声明QpushButton,在CPP文件中实现。在主窗口中包含头文件。子窗口初始化代码:

Subwidget::Subwidget(QWidget *parent) : QWidget(parent)
{
    b1 = new QPushButton("中腾",this);
    b1->resize(100,100);
    setWindowTitle("软件园窗口");
    resize(400,600);
}

主窗口头文件包含代码:

	QPushButton *b3; //作用显示子窗口
    //子窗口的对象
    Subwidget subW;

主窗口cpp文件包含代码:

//b3显示子窗口Subwidget --subW
    b3 = new QPushButton("软件园",this);
    b3->resize(150,150);
    b3->move(200,200);
   //注意这里是创建的指针类型的b3不需要取地址符。
   connect(b3,&QPushButton::clicked,this,&Widget::slotHindMe);

然后从中腾返回主窗口的实现。要发送一个信号回到主窗口。

Subwidget::Subwidget(QWidget *parent) : QWidget(parent)
{
    b1 = new QPushButton("中腾",this);
    b1->resize(100,100);
    setWindowTitle("软件园窗口");
    resize(400,600);
    //给主窗口发送信号
    connect(b1,&QPushButton::clicked,this,&Subwidget::myslot);
}
void Subwidget::myslot()
{
    //发送信号
    emit sigSub();
}

在主窗口widget中实现:

connect(&subW,&Subwidget::sigSub,this,&Widget::slotShowMe);
void Widget::slotShowMe()
{
        //显示自己
        show();
        //显示软件园
        subW.hide();
}

重载的信号槽

信号槽不仅仅能发送一个信号,可以发送多个信号,发送多个信号的时候要用到函数指针,对多个信号进行重载,其次,还要声明作用域。如果信号和槽发生重载,要定义函数指针显示定义。

void Subwidget::myslot()
{
    //发送信号
    emit sigSub();
    emit sigSub(250,"你是250");
}
   connect(b3,&QPushButton::clicked,this,&Widget::slotHindMe);
   void (Subwidget::*MySigSub)()=&Subwidget::sigSub;
   connect(&subW,MySigSub,this,&Widget::slotShowMe);
   void (Subwidget::*MySigPlus)(int ,QString)=&Subwidget::sigSub;
   connect(&subW,MySigPlus,this,&Widget::slotSubMag);

拓展:1、信号可以连接信号
2、一个信号可以连接多个槽函数
3、多个信号可以连接一个槽函数
4、槽函数可以使用lambda表达式

lambda表达式

[=](){}值传递的方式,可以使用到函数外的参数。[&](){}引用外部的地址。[this](){}可以使用当前类的成员变量。[a](){}值传递的方式,可以传递a的值,大括号只能使用a。
使用lambad表达式作为槽函数。

第一天的复习内容

1、创建QT程序

1、一个Qt程序的组成部分:应用程序类,窗口类
2、应用程序类的个数:有且只有一个,QApplication a;
3、如何查看对应的模块:
光标移动到类上,F1
qmake += 模块的名字

2、第一个Qt程序

1>在窗口中添加按钮
类名:QPushButton
设置按钮显示的内容:setText
移动按钮的位置:move
按钮设置父窗口:setParent
设置窗口的大小:resize(),resizeFixed()
2>Qt的坐标体系:
坐标原点:左上角
x轴延伸方向:向右
y轴延伸方向:向下
3>Qt的内存回收机制
满足什么条件不需要用户手动释放内存?
1.从QObject类直接或间接派生。
2.从直接或间接派生出的类,指定父对象。

3、信号和槽

1>.格式:connect(信号发出者对象(指针),&className::clicked,信号接收者对象(指针),&classB::slot);
2>.标准信号槽的使用:
3>.自定义槽函数:
1:返回值void
2:可以重载
3:需要和信号对应,个数<=信号的参数个数
4>.自定义信号
1:返回值void
2:可以重载
3:需要使用一个关键字声明:signals;
4:不需要函数定义
5>.单参数的信号(槽)
1:重载的时候:信号槽发生了重载,需要使用函数指针。
2:Qt4信号槽的使用
SIGNAL(信号的函数名()),SLOT(槽函数名(int,long))
connect 连接 重载过的信号和槽的解决方法。

6>.拓展:
a.信号可以链接信号(参数的对应)。
b.一个信号可以链接多个槽函数
c.多个信号可以链接同一个槽函数
d.槽函数可以使用lambda表达式

4、QMainWindow
	1>.菜单栏
	2>.工具栏
	3>.浮动窗口和核心部件
	4>.状态栏
5、QDialog
	1>.模态对话框
	2>.非模态对话框
	3>.标准对话框和文件对话框

Day_1 课程总结精炼


	Me wo;
	Beauty sweet;//小红
	Beauty sweet1;//小紫
//场景:
1>. 我 看到 美女 之后 ,我直流口水    //自己给自己发信号
connect(&wo,&Me::seeBeauty,&wo,&Me::mouthWatering);
2>.我 调戏 美女 , 美女抽我		//我发信号,其他人接收
connect(&wo,&Me::molestBeauty,&sweet,&Beauty::beatSomebody);
3>.我给两个美女些情书,一个同意,一个拒绝  //槽函数的参数个数<信号的参数个数
//1.信号和槽重载的时候,需要使用到函数指针
//2.同一个信号和槽,可以链接多个槽函数
void (Beauty::*slotAnswer)()=&Beauty::answer;
connect(&wo,&Me::writeLoveLetter,&sweet,slotAnswer);


void (Beauty::*slotAnswer1)(QString)=&Beauty::answer;
connect(&wo,&Me::writeLoveLetter,&sweet,slotAnswer);

4>.我拜托小红把情书给她的双胞胎妹妹小紫,小紫说我只喜欢会Qt的程序猿
//信号链接信号
connect(&wo,&Me::weituoLetter,&sweet1,&Beauty::sendLetter);

connect(&sweet1,&Beauty::sendLetter,&sweet,&Beauty::slotAnswer1);
	

DAY_02

QMainWindow

介绍UI界面,创建UI界面之后,如下:无法改变英文名,点击text输入中文,改变名称。
QT5入门学习(一)_第8张图片
在这里插入图片描述

 connect(ui->actionopen,&QAction::triggered,this,[=]()
    {
        QString name =  QFileDialog::getOpenFileName(this,"打开文件","D:\\","Image(*.jpg *.png)");
        qDebug() << name;
    });

讲解了浮动窗口的应用,如何使用浮动窗口。设置状态为floating,默认状态为浮动。
下面勾选框设置允许停靠的位置。
QT5入门学习(一)_第9张图片

1、资源文件的添加

在项目文件上右击添加新文件,选择天机resource file 添加新文件。添加成功后右击,加入前缀和反斜杠。把资源文件夹复制到工程文件夹下面,之后添加资源图片。

QT5入门学习(一)_第10张图片在mainwindow.cpp中添加代码如下。

 ui->actionSave_as->setIcon(QIcon(":/IMAGE/3.png"));

即可显示出资源图片:
QT5入门学习(一)_第11张图片
如果项目比较大,可以添加不同的前缀来添加文件。

资源文件的更简单的使用方法:左侧选择中标签,之后在资源管理中找到icon,在normal中添加资源中的图片

QT5入门学习(一)_第12张图片

2、对话框-QDialog

模态&非模态对话框
非模态对话框:打开之后可以其他界面进行其他操作。
模态对话框:打开之后不可以其他界面进行其他操作。

connect(ui->actionopen,&QAction::triggered,this,[=]()
    {
        //显示模态对话框 exec
        QDialog log(this);//定义一个父类对象,表示只有这一个窗口
        log.exec();//阻塞状态。
        QString name =  QFileDialog::getOpenFileName(this,"打开文件","D:\\","Image(*.jpg *.png)");
        qDebug() << name;
    });
    connect(ui->actionsave,&QAction::triggered,this,[=]()
    {
        //非模态对话框要保证在完成之前不被析构掉。只有当主窗口关闭之后才会被析构掉。
        QDialog *log =new QDialog(this);
        //显示非模态对话框 show()
        //设置对话框的属性
        log->show(); //非阻塞状态
        log->setAttribute(Qt::WA_DeleteOnClose);//让对话框删除。
        QString name =  QFileDialog::getOpenFileName(this,"打开文件","D:\\","Image(*.jpg *.png)");
        qDebug() << name;
    });

3、QMessageBox

实现包含的头文件 #include
实现代码:

 QMessageBox::about(this,"about","++++++");

实现现象:
QT5入门学习(一)_第13张图片
四种消息提示符:
QT5入门学习(一)_第14张图片
如果执行了OK之后会出现的界面情况,最后一个参数为默认按钮,添加成功之后的界面,按下回车,按钮会响应回车按键:

 if(QMessageBox::Ok == QMessageBox::critical(this,"error","系统文件错误!!!",QMessageBox::Ok|QMessageBox::Cancel,QMessageBox::Cancel))
       {
                   //显示模态对话框 exec
                   QDialog log(this);
                   log.exec();//阻塞

       }

4、颜色和字体对话框

所需要包含的头文件:
#include
#include
返回值是QColor 获得颜色对话框。之后打印出红绿蓝的颜色属性。

        QColor color = QColorDialog::getColor();
        qDebug()<<color.red()<<color.green()<<color.blue();

返回值是QFont 获得字体的对话框,之后打印出字体属性(斜体,字体大小,加粗);

       bool ok;
       QFont font = QFontDialog::getFont(&ok,QFont("华文彩云"),this,"我的字体设置");
       if(ok)
       {
         qDebug()<<font.family()<<font.italic()<<font.pointSize()<<font.bold();
       }

5、布局

在开始布局之前首先为每一组控件创建一个父窗口。设置完成之后,界面如图所示。
QT5入门学习(一)_第15张图片
为窗口设定最大宽度、高度和最小宽度、高度,来让界面固定大小。
QT5入门学习(一)_第16张图片
网格布局:让每行每列的对齐,可以显示当行多列,每一列的宽度是相等的。
美化完成之后,选中对话框可以设置最后的间距大小,可以设置和边界的最后距离。
QT5入门学习(一)_第17张图片布局的时候,就是布局套布局,一层层布局下去。

6、按钮控件

1–PushButton按钮。
首先拖拽一个Button按钮放在UI界面上,在.cpp文件中,按下F1进入帮助文档,查看帮助文档信息,查看父类,在点击Signals。查看可以使用的信号。

QT5入门学习(一)_第18张图片

每个控件放置在界面内一定要布置布局。
信号操作使用的实例:

 connect(ui->radioButton,&QAbstractButton::clicked,this,[=]()
    {
        QMessageBox::information(this,"打印正确","hhhh");
    });

单选框和复选框:
QT5入门学习(一)_第19张图片
复选框使用示例,打印出控件的状态:

 connect(ui->checkBox,&QCheckBox::stateChanged,this,[=](int state)
    {
        qDebug()<<state;
    });

7、控件介绍

在QListWidget:控件中添加图片和文字。

	ui->listWidget->addItem("软件创业园");
    ui->listWidget->addItem(new QListWidgetItem(QIcon("D:\\1.png"),"Lufft"));

效果如下图所示:
在这里插入图片描述
table widget的使用:

 	//1、指定行数
    ui->tableWidget->setRowCount(5);
   //2、指定列数
    ui->tableWidget->setColumnCount(3);
    QStringList list;
    list<<"姓名"<<"性别"<<"年龄";
    ui->tableWidget->setHorizontalHeaderLabels(list);

测试结果:
QT5入门学习(一)_第20张图片

滚动条区域:Scroll Area
QT5入门学习(一)_第21张图片

Tool Box:
就像QQ列表的使用一样,点击一次按钮,就打开一次列表界面,使用效果如下图所示:
QT5入门学习(一)_第22张图片QT5入门学习(一)_第23张图片

TabWidget:分开显示界面。
QT5入门学习(一)_第24张图片

栈窗口:Stacked Widget
结果如下图所示:通过按键按钮,然后切换不同的界面。与QTabWidget 的区别是:这个控件和按钮是独立的,而QTabWidget是有联系的。
QT5入门学习(一)_第25张图片QT5入门学习(一)_第26张图片
QT5入门学习(一)_第27张图片
序号是当前窗口的currentIndex:

 connect(ui->musicBtn,&QPushButton::clicked,this,[=]()
    {
        ui->stackedWidget->setCurrentIndex(0);
    });
     connect(ui->otherBtn,&QPushButton::clicked,this,[=]()
    {
        ui->stackedWidget->setCurrentIndex(1);
    });
     connect(ui->movieBtn,&QPushButton::clicked,this,[=]()
    {
        ui->stackedWidget->setCurrentIndex(2);
    });

Combobox:
下拉框选择123进入电影界面。
QT5入门学习(一)_第28张图片

 connect(ui->comboBox,&QComboBox::currentTextChanged ,this,[=]()
     {
         ui->stackedWidget->setCurrentIndex(2);
     });

Qlabel类

在Qt中,QPixmap代表的是一张图片。如何插入图片呢?
首先添加资源文件,在UI界面添加lable控件,之后添加代码:

ui->image->setPixmap(QPixmap(":/IMAGE/3.png"));

结果显示如下:
QT5入门学习(一)_第29张图片

为了显示动图:要在头文件添加 #include,之后添加如下代码:

	 QMovie* movie = new QMovie(":/IMAGE/4.gif");
     ui->image->setMovie(movie);
     movie->start();

显示动态小猫咪如下图所示:
QT5入门学习(一)_第30张图片

DAY_03

自定义控件:封装一个控件的时候,先对疯转搞的控件进行处理。
首先添加一个文件,在文件中创建一部分控件。紧接着在主窗口把主窗口提升为之前设置的子窗口,默认选择全局包含,这样在之后的创建过程中,其他控件也可以提升为之前的子控件。
QT5入门学习(一)_第31张图片

QT5入门学习(一)_第32张图片
QT5入门学习(一)_第33张图片
在smallwidget中先对里面的控件进行处理,添加如下代码:

  void(QSpinBox::*sigValueChange)(int) = &QSpinBox::valueChanged;
   connect(ui->spinBox,sigValueChange,ui->horizontalSlider,&QSlider::setValue;
connect(ui->horizontalSlider,&QSlider::valueChanged,ui->spinBox,&QSpinBox::setValue);

实现功能数字变化,滑块也变化。滑块变化,数字也变化。
QT5入门学习(一)_第34张图片

小技巧:在使用控件的时候,做错了,重新更改边框,在widget右击变形为。。。

事件

在项目中添加新的C++文件,在C++文件上继承Qlabel,之后重写被保护的虚函数,虚函数的查看,在Qlabel中按下F1。QLabel是从QWidget中派生的。
QT5入门学习(一)_第35张图片

QT5入门学习(一)_第36张图片
实际上这些事件都是回调函数,我们只需要对这些函数进行功能实现即可。

QString 字符串的拼接

//字符串的拼接 QString().arg()
   //%1,%2,%3 --占位符
    QString str = QString("%3,%2,%1").arg(1).arg("123").arg('a');

拼接后的结果如图所示:
在这里插入图片描述
鼠标事件的代码:

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


// QWidget 默认不追踪鼠标事件的
Mylabel::Mylabel(QWidget *parent) : QLabel(parent)
{
       //设置窗口追踪鼠标键
    this->setMouseTracking(true);
}
//进入和离开都是在边界的那一瞬间完成的。
//鼠标进入
void Mylabel::enterEvent(QEvent *)
{
    setText("鼠标进入");
}
//鼠标离开
void Mylabel::leaveEvent(QEvent *)
{
    setText("鼠标离开~");
}
//鼠标按下
void Mylabel::mousePressEvent(QMouseEvent *ev)
{
   //字符串的拼接 QString().arg()
   //%1,%2,%3 --占位符
    QString btn;
    if(ev->button()==Qt::LeftButton)
    {
        btn = "LeftButton";

    }
    else if(ev->button()==Qt::RightButton)
    {
        btn = "RightButton";
    }
    else if(ev->button()==Qt::MidButton)
    {
        btn = "MidButton";
    }
    QString str = QString("MousePress[%3]:(%1,%2)").arg(ev->x()).arg(ev->y()).arg(btn);
    setText(str);

}
//鼠标释放 这是个瞬间的状态
void Mylabel::mouseReleaseEvent(QMouseEvent *ev)
{
    //字符串的拼接 QString().arg()
    //%1,%2,%3 --占位符
     QString btn;
     if(ev->button()==Qt::LeftButton)
     {
         btn = "LeftButton";

     }
     else if(ev->button()==Qt::RightButton)
     {
         btn = "RightButton";
     }
     else if(ev->button()==Qt::MidButton)
     {
         btn = "MidButton";
     }
     QString str = QString("MouseRelease[%3]:(%1,%2)").arg(ev->x()).arg(ev->y()).arg(btn);
     setText(str);
}
//鼠标移动    移动操作比较特殊 要按位与操作才能捕捉鼠标对象。这是个持续的状态。
void Mylabel::mouseMoveEvent(QMouseEvent *ev)
{
    //字符串的拼接 QString().arg()
    //%1,%2,%3 --占位符
     QString btn;
     if(ev->buttons()&Qt::LeftButton)
     {
         btn = "LeftButton";
 
     }
     else if(ev->buttons()&Qt::RightButton)
     {
         btn = "RightButton";
     }
     else if(ev->buttons()&Qt::MidButton)
     {
         btn = "MidButton";
     }
     QString str = QString("MousePress[%3]:(%1,%2)").arg(ev->x()).arg(ev->y()).arg(btn);
     setText(str);
}

定时器

使用方法一:
首先包含timerevent 的头文件,其次在窗口的构造函数中启动定时器。id = startTimer(100);参数100代表100ms触发一次。添加代码如下 实现启动定时器。当num>=100的时候关闭定时器。

 //每触发一次定时器,就进入一次函数
        static int num = 0;
        QString str = QString("%1:%2").arg("Time out").arg(num++);
        if(num >= 100)
        {
            //关闭定时器
            killTimer(id);
        }

QT5入门学习(一)_第37张图片

使用方法2:
首先包含头文件QTimer,在构造函数中创建一个对象,创建对象完成之后,mylabel构造函数中添加如下代码,启动定时器:

//第二种定时器的使用方式
    QTimer *timer = new QTimer(this);
    timer->start(100);

    connect(timer,&QTimer::timeout,this,[=]()
    {
        static int number=0;
        QString str = QString("%1:%2").arg("Time out").arg(number++);
        this->setText(str);
    });

QT5入门学习(一)_第38张图片

QPrinter

首先在widget.cpp中包含头文件“#include ”,如果我们想在当前窗口绘图的话,我们需要重载一个虚函数。

protected:
    /*
    * 1-回调函数
    * 2-此函数不需要用户调用,在刷新的时候回自动调用
    *       1.窗口显示的试试
    *       2.最大化,最小化
    *       3.窗口被遮挡重现显示的试试
    *       4.用户强制刷新的时候
    * 3-如果想使用画家类画图,操作必须在paintevent完成
    */
     void paintEvent(QPaintEvent *event);
void Widget::paintEvent(QPaintEvent *)
{
    //创建画家类对象
    QPainter p(this);  //指定绘图设备,不是父对象
    // 创建新画笔  -- 轮廓
    QPen pen;
    pen.setColor(/*Qt::green*/QColor(0,255,0));
    pen.setWidth(10);
    pen.setStyle(Qt::DotLine);
    //闭合区域使用画刷 -- 填充闭合区域
    //QBrush brush(Qt::blue);
    QBrush brush(QPixmap(":/IMAGE/3.png"));
    p.setBrush(brush);
    //将新画笔设置给画家类
    p.setPen(pen);
    //画背景图
    p.drawPixmap(0,0,QPixmap(":/IMAGE/3.png"));
    //画直线
    p.drawLine(QPoint(100,100),QPoint(300,500));
    //画椭圆
    p.drawEllipse(QPoint(200,100),100,50);
    //画矩形
    p.drawRect(400,200,200,200);
    //写字
    QFont font("华文彩云",48,75,true); //定义字体类
    p.setFont(font);//调用字体类
    p.drawText(100,400,"我是你哥哥");
}

强制刷新界面

首先定义变量x;在UI界面添加按键,添加按键之后,创建槽函数。

 connect(ui->move,&QPushButton::clicked,this,[=]()
    {

        //刷新窗口
        update();//系统调用paintEvent

    });

再完成槽函数之后,在 void Widget::paintEvent(QPaintEvent *)添加如下代码。

 int width = this->width();
    int height = this->height();
    x+=5;
    //提供笑脸
    if(x>this->width())
    {
        x=20;
    }
    p.drawPixmap(x,100,QPixmap(":/IMAGE/1.png"));

单击按键移动可以实现图片一直向右移动,即使跑出界面,也可以再进入界面。
QT5入门学习(一)_第39张图片

绘图设备

在widget添加如下代码:

 ui->setupUi(this);
    QPixmap pix(300,300);//纸的大小
    pix.fill(Qt::red);//给纸张填充颜色
    QPainter p(&pix);//定义画家类
    p.setPen(QPen(Qt::green,10));//设置画笔颜色,粗细
    p.drawRect(10,10,280,280);//绘制矩形
    p.drawEllipse(150,150,50,50);//绘制圆形
    pix.save("D:\\mypixmap.jpg");

    //指定绘图设备 1.构造函数中(参数是绘图设备)
    //2.begin(参数是绘图设备)
    //     end;
    //在QImage中绘图
    QImage img(300,300,QImage::Format_RGB32);//纸的大小
    img.fill(Qt::red);//填充为红色

    p.begin(&img);//开始绘制图片
    p.setPen(QPen(Qt::green,10));
    p.drawRect(10,10,280,280);
    p.drawEllipse(150,150,50,50);
    p.end();//结束绘制图片
    img.save("D:\\myimage.jpg");
    
    //在Qpicture中绘图
    //1.保存的是绘图步骤 --画家类
    //2.不是图片 是二进制文件 (save 保存生成的文件)
    //3.不依赖于平台
    QPicture pic;//纸的大小
    p.begin(&pic);//开始绘制图片
    p.setPen(QPen(Qt::green,10));
    p.drawRect(10,10,280,280);
    p.drawEllipse(150,150,50,50);
    p.end();//结束绘制图片
    pic.save("D:\\mypic.jpg");

显示picture

void Widget::paintEvent(QPaintEvent *event)
{
    QPainter p(this);
    QPicture pic;
    pic.load("D:\\mypic.jpg");
    p.drawPicture(100,100,pic);

}

实现画图功能

QT5入门学习(一)_第40张图片

不规则窗口

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

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    //加载图片
    pix.load("D:\\3.png");
    //去掉边框函数
    this->setWindowFlag(Qt::FramelessWindowHint);
    //设置背景透明函数
    this->setAttribute(Qt::WA_TranslucentBackground);
}
Widget::~Widget()
{
    delete ui;
}
void Widget::paintEvent(QPaintEvent *event)
{
    //在窗口中把图片画出来
    QPainter p(this);
    p.drawPixmap(0,0,pix);

}
void Widget::mousePressEvent(QMouseEvent *event)
{
    if(event->button() == Qt::LeftButton)
    {
       //求差值  左键按下的点减去窗口左上角的点的坐标
       pq = event->globalPos() - this->frameGeometry().topLeft();

    }
    else if(event->button() == Qt::RightButton)
    {
        // close window
        this->close();
    }
}
void Widget::mouseMoveEvent(QMouseEvent *e)
{
    //move x,y 使用屏幕坐标系
    //e->x(),e->y()  窗口的坐标系 Widget
    this->move(e->globalPos() - pq);

}

实现用鼠标移动图标功能,单击右键实现关闭图片功能。
QT5入门学习(一)_第41张图片

你可能感兴趣的:(QT,qt,c++)