文章目录
绘图
QPixmap类:绘图
- 使用QLabel或QAbstractButton的子类之一(例如QPushButton和QToolButton),可以轻松地在屏幕上显示QPixmap
- QLabel具有pixmap属性,而QAbstractButton具有icon属性
# 创建一个空的 pixmap, 并设定其尺寸
self.pix = QtGui.QPixmap(300, 300) # 默认填充颜色为黑色
self.pix.fill('red') # 修改填充颜色为红色
self.setPixmap(self.pix) # 设定 QLabel 的 pixmap
QPixmap::scaled(): 根据给定的尺寸来放大缩小QPixmap
QPixmap::scaled(const QSize & size, Qt::AspectRatioMode aspectRatioMode = Qt::IgnoreAspectRatio, Qt::TransformationMode transformMode = Qt::FastTransformation) const
IgnoreAspectRatio
矩形框有多大,图片就缩放成多大,不限制原图片的长宽比KeepAspectRatio
保持原图片的长宽比,且不超过矩形框的大小KeepAspectRatioByExpanding
根据矩形框的大小最大缩放图片
QPixmap为QLabel设置背景图片
QPixmap pixmap = QPixmap(":/xxx/xx.png").scaled(labelName->rect().size(), aspectMode);
ui->label->setPixmap(pixmap);
QLineEdit的样式只能通过QPalette
QPixmap VS QImage
- QPixmap依赖于硬件,QImage不依赖于硬件。
- QPixmap主要是用于绘图,针对屏幕显示而最佳化设计,QImage主要是为图像I/O、图片访问和像素修改而设计的。
- 当图片小的情况下,直接用QPixmap进行加载,画图时无所谓,当图片大的时候如果直接用QPixmap进行加载,会占很大的内存,一般一张几十K的图片,用QPixmap加载进来会放大很多倍,所以一般图片大的情况下,用QImage进行加载,然后转乘QPixmap用户绘制。QPixmap绘制效果是最好的。
paintEvent(QPaintEvent*) 绘图
注意:在编译器中resource中要包含该图片文件
- 主要提供在窗体或者其他绘图设备上进行绘图的功能。
- QWidget类中的虚函数,用于ui的绘制,会在多种情况下被其他函数自动调用。
- 常用函数:
- drawXXX()函数,用于绘制图形、文字和路径等;
- fillXXX()函数,用于填充,可在指定区域内进行填充;
- brush()和pen() 笔刷和钢笔的相关操作
// 只要是继承自QWidget都会自动调用
void QWidget::paintEvent(QPaintEvent *event){
QPixmap pixmap = QPixmap(":/Resource/images/LoginImg/BG.png").scaled(this->size()); // 设置为整个页面的背景
QPainter painter(this);
painter.drawPixmap(rect(), pixmap, QRect());
}
当发生一下情况时会产生绘制事件并调用paintEvent()函数:
- 在窗口部件第一次显示时,系统会自动产生一个绘图事件,从而强制绘制这个窗口部件。
- 当重新调整窗口部件的大小时,系统也会产生一个绘制事件。
- 当窗口部件被其他窗口部件遮挡,然后又再次显示出来的时候,就会对那些隐藏的区域产生一个绘制事件。
同时可以调用QWidget::update()
或者QWidget::repaint()
来强制产生一个绘制事件。二者的区别是:
repaint()函数会强制产生一个即时的重绘事件,而update()函数只是在Qt下一次处理事件时才调用一次绘制事件。
如果多次调用update(),Qt会把连续多次的绘制事件压缩成一个单一的绘制事件,这样可避免闪烁现象。
QIcon
QPalette类:调色板
- 对话框或控件的调色板
- 管理控件或窗体的所有颜色信息,每个窗体或控件都包含一个QPalette对象,在显示时按照它的QPalette对象中对各部分各状态下的颜色的描述来进行绘制。
ColorGroup
QPalette::Disabled 不可用状态
QPalette::Active 活跃状态(获得焦点)
QPalette::Inactive 不活跃状态(未获得焦点)
ColorRole
QPalette::Window 一个常规的背景颜色
QPalette::Background 这个值是废弃的,使用window代替
QPalette::WindowText 一个一般的前景颜色
QPalette::Foreground 这个值是废弃的,使用windowText代替.
QPalette::Base 最长使用来作为text背景颜色为整个widget,但是也能被用来为其他的绘画,像combobox的上下清单的背景和工具栏句柄。它通常是白的或者其他亮的颜色.
QPalette::AlternateBase 被用来作为轮流的背景颜色,轮流的行颜色
QPalette::ToolTipBase 被用来作为背景颜色为QToolTip和QWhatsThis。工具尖端使用QPalette不活跃的颜色组,因为工具尖端不是活跃的窗口.
QPalette::ToolTipText 被用来作为前景颜色为QToolTip和QWhatsThis.工具尖端使用QPalette不活跃的颜色组,因为工具尖端不是活跃的窗口.
QPalette::Text 前景颜色使用base.这通常和windowText相同,它一定提供好的对比window和base
QPalette::Button button背景颜色。这个背景颜色能是不同于window作为一些风格,要求一个不同的背景颜色作为button
QPalette::ButtonText 一个前景颜色被用来作为button颜色.
QPalette::BrightText 一个text颜色是很不同于windowText,很好的对比与dark。典型的被用来为text,需要被画,在text或者windowText将给差的对比,就像在按下的button。注意text颜色能被用来为事情,而不只是单词;text颜色通常被用来为text,但是他是相当普通的使用text颜色角色为行,图标,等等。
QBrush画刷
//注意要先调用setAutoFillBackground
textEdit->setAutoFillBackground(true);
QPalette palette;
//设置QTextEdit文字颜色
palette.setBrush(QPalette::Active, QPalette::Text, QBrush(Qt::yellow));
//设置QTextEdit背景色
palette.setBrush(QPalette::Active, QPalette::Base, QBrush(Qt::red));
textEdit->setPalette(palette);
常用设置颜色方法
void QPalette::setBrush ( ColorRole role, const QBrush & brush )
改变所有组下指定角色role的画刷颜色值。void QPalette::setBrush ( ColorGroup group, ColorRole role, const QBrush & brush )
改变指定组group下的指定角色role的画刷颜色值。void QPalette::setColor ( ColorRole role, const QColor & color )
改变所有组下指定角色role的颜色值。void QPalette::setColor ( ColorGroup group, ColorRole role, const QColor & color )
改变指定组group下指定角色role的颜色值。
ps: 在以上代码之前,必须先调用函数 void setAutoFillBackground ( bool enabled );
设置窗体运行自动填充、对话框和控件的背景色
QLineEdit设置背景颜色
QPalette palette(ui->lineEdit->palette());
palette.setBrush(QPalette::Base, QBrush(QColor(255,0,0,0))); // 设置背景透明,QColor最后一个参数为透明度
palette.setBrush(QPalette::Text, QBrush(QColor(255,255,255))); // 设置文字颜色
edtName->setPalette(palette);
edtName->setFrame(false); // 取消边框
登录按钮制作 Trick
在图片上加文字
先用QImage创建图片,再用QPixmap显示图片
使用setWhatsThis可以获取到不同QPushButton的属性
https://blog.csdn.net/qianqiaoqianqi/article/details/110848718
QPixmap QPixmap::fromImage(QImage(":/xxx/btn-登录.png"));
QPainter painter(&pixmap);
//painter.begin(&pixmap);
painter.setPen(Qt::white);
QFont font = painter.font();
font.setPixelSize(12);
font.setBold(true);
font.setLetterSpacing(QFont::PercentageSpacing, 120);
font.setFamily("Microsoft YaHei");
painter.setFont(font);
painter.drawText(pixmap.rect(), Qt::AlignCenter, QString("登录").toStdString().c_str()); // setWhatsThis
// painter.setPen(QPen(Qt::green,3));
// painter.drawRect(pixmap.rect());
// painter.setPen(QPen(Qt::red,3));
// painter.drawRect(btnName->rect());
这样我们得到的pix图片就是已经在原图片上添加了文本的,新生成的一张图了,再根据需求直接调用pix。
将带文字的图片作为pix给QPushButton显示
btnName->setIcon(QIcon(pixmap));
btnName->setIconSize(ui->pushButton_login->rect().size());
btnName->setFlat(true);
btnName->setFocusPolicy(Qt::NoFocus);
// btnName->setStyleSheet("border:none");
常见问题
p.load()将图片加载到缓冲区QPixmapCache中,当你加载图片二是,图片一并没有被覆盖,此时缓冲区内有图片一和图片二,当你再次加载图片一时,缓冲区里有了,所以p.load()直接返回true;但是图片仍是图片二,所以不能显示回图片一。
解决方案:
- 直接定义局部变量,这样每次都是新的缓冲区;
- 当再次加载图片时,先将缓冲区清空, QPixmapCache::clear();然后再加载;
- 在初始化函数里写:QPixmapCache::setCacheLimit(1);设置缓冲区内只能放一张图片
为继承自QWidget的界面添加样式: 未重写paintEvent(QPaintEvent *e)函数
https://doc.qt.io/qt-5/stylesheet-reference.html中有如下介绍:
Supports only the background, background-clip and background-origin properties.
If you subclass from QWidget, you need to provide a paintEvent for your custom QWidget as below:
void CustomWidget::paintEvent(QPaintEvent *)
{
QStyleOption opt;
opt.init(this);
QPainter p(this);
style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
}
The above code is a no-operation if there is no stylesheet set.
Warning: Make sure you define the Q_OBJECT macro for your custom widget.
解决方案:
-
添加
paintEvent(QPaintEvent *){}
https://www.dazhuanlan.com/wanghttt812/topics/1173634 -
Setting Qt::WA_StyledBackground to true only works if you remember to add Q_OBJECT to your class. With these two changes you don’t need to reimplement paintEvent.
setAttribute(Qt::WA_StyledBackground, true)
另外还需要注意的是:如果在 Qt Designer 中改变样式表来设置背景图的话,最好别用 objectName 来作为 QSS 的选择器。因为提升后的 widget 对象名已经改变!可以用类名作为选择器。
https://stackoverflow.com/questions/7276330/qt-stylesheet-for-custom-widget
https://beyondyuanshu.github.io/2019/09/16/why-does-qwidget-disappear-after-promoted.html
按键加图片文字
BtnYes = new QToolButton(this);
BtnYes->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
QPixmap yesPix(":/res/yesBtn.png");
BtnYes->setIcon(yesPix);
BtnYes->setIconSize(QSize(26, 24));
资料
https://baijiahao.baidu.com/s?id=1625725042120987082&wfr=spider&for=pc