11 自定义信号和槽发生重载的解决
信号
signals:
void hungry();
void hungry(QString foodName);
发送信号
emit hungry("鸡肉");
槽
void Student::treat(){
qDebug() << "请吃饭";
}
void Student::treat(QString foodName){
//QString类型打印会自己带上引号,为了不带引号,需要把QString转为char *类型,用到.toUtf8().data()
qDebug() << "请吃饭,吃" << foodName.toUtf8().data();
}
连接信号和槽
//connect(zt,&Teacher::hungry,st,&Student::treat);
//由于有重载,信号和槽的地址不能确定为哪一个。
//指针可以指向地址,所以要将函数指针指向函数地址,然后用指针代替
void (Teacher:: *teacherSignal)(QString) = &Teacher::hungry;
//返回值(作用域::函数指针)(参数类型) = 函数地址;
void (Student:: *studentSlot)(QString) = &Student::treat;
connect(zt,teacherSignal,st,studentSlot);
14
a
Lambda C++11
匿名函数
[](){}();
- 中括号
= 值传递
& 应用传递 - 小括号
参数 - 大括号
函数体 - 小括号
负责调用上述声明
b
mutable关键字:用于修饰值传递的变量,修改拷贝,而不是修改值本身
int m = 10;
[m]()mutable{//默认m只读。使用关键字改为可修改状态
m = 100 + 10;
qDebug() << m;
};
c. 非void返回
int ret = []()->int{return 1000}();
qDebug() <<ret;
d. 省略第三个参数this
若用Lambda表达式,且第三个参数是this,可省略this
connect(btn,&QPushButton::clicked,[=](){
btn->setText("aaa");
});
17
QMainWindow创建菜单栏
/***********创建菜单栏,只能对多有一个************/
QMenuBar * bar = menuBar();
//将菜单栏放入到窗口
serMenuBar(bar);
//创建菜单
QMenu * fileMenu = bar->addMenu("文件");
QMenu * editMenu = bar->addMenu("编辑");
//创建菜单项
fileMenu->addAction("新建");
//添加分割线
fileMenu->addSeparator();
fileMenu->addAction("打开");
/***************工具栏,可以有多个***********/
QToolBar * toolBar = new QToolBar(this);
//后期设置,只允许左右停靠。
toolBar->addToolBar(Qt::LeftToolBarAreas ||Qt::RightToolBarAreas)
//设置浮动
toolBar->setFloatable(false);
//设置移动(总开关)
toolBar->setMovable(false);
//工具栏中可以设置内容
toolBar->addAction(openAction);
//工具栏中添加控件
QPushButton *btn = new QPushButton("aa", this);
toolBar->addWidget(btn);
代码片段
1. widget透明,内部部件不透明
setAttribute(Qt::WA_TranslucentBackground, true);
2. widget去除title栏
setWindowFlag(Qt::FramelessWindowHint);
3. 画折线
#include <QPainter>
void Switch::paintEvent(QPaintEvent *)
{
static const QPointF points[3] = {
QPointF(15.0, 5.0),
QPointF(5.0, 25.0),
QPointF(15.0, 45.0),
};
QPainter painter(this);
painter.setRenderHint(QPainter::SmoothPixmapTransform, true);
painter.setRenderHint(QPainter::HighQualityAntialiasing, true);
painter.setPen(QPen(QBrush(Qt::darkGray), 4, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
painter.drawPolyline(points, 3);
}
画直线
#include <QPainter>
void MainWindow::paintEvent(QPaintEvent *)
{
//创建一个QPainter对象,用于后面的绘制
QPainter painter1(this);
//使用drawLine()函数绘制了一条线段,线段的起点为(0, 0),终点为(100, 100) ,这里的单位是像素
painter1.drawLine(QPointF(0, 0), QPointF(100, 100));
}
画椭圆
#include <QPainter>
void MainWindow::paintEvent(QPaintEvent *)
{
QRect rectangle(10.0, 20.0, 80.0, 60.0);
QPainter painter2(this);
painter2.drawEllipse(rectangle);
painter2.setRenderHint(QPainter::SmoothPixmapTransform, true);
painter2.setRenderHint(QPainter::HighQualityAntialiasing, true);
}
抗锯齿绘图
enum QPainter::RenderHint
QPainter::Antialiasing //原始边缘的抗锯齿绘制
QPainter::TextAntialiasing //文字的平滑绘制,若禁止使用文字抗锯齿,不要使用此hint
QPainter::SmoothPixmapTransform //使用平滑的pixmap变换算法(双线性插值算法),而不是近邻插值算
QPainter::HighQualityAntialiasing //过时。使用QPainter::Antialiasing 即可
QPainter::NonCosmeticDefaultPen //过时
举例:
painter.setRenderHint(QPainter::Antialiasing, true);//
-
我们通过这条语句,将Antialiasing属性(也就是反走样)设置为
true。经过这句设置,我们就打开了QPainter的反走样功能。 -
由于反走样需要比较复杂的算法,在一些对图像质量要求不是很高的应用中,是不需要进行反走样的。为了提高效率,一般的图形绘制系统,都是默认不进行反走样的。
举例:
painter->setRenderHints(QPainter::SmoothPixmapTransform);//消锯齿
笔刷和画刷
#include <QPainter>
void MainWindow::paintEvent(QPaintEvent *)
{
QPainter painter(this);
//笔刷
QPen pen;
//画笔使用了setColor()函数为其设置了颜色
pen.setColor(QColor(255,0,0));
//画刷是在构建的时候直接为其设置的颜色
QBrush brush(QColor(0,255,0,125));
//将画笔和画刷设置到了painter上
painter.setPen(pen);
painter.setBrush(brush);
//使用drawRect()绘制了一个矩形,其左上角顶点在(50, 50),宽为200,高为100
painter.drawRect(50,50,200,100);
}
举例
void MainWindow::paintEvent(QPaintEvent *)
{
QPainter painter(this);
QPen pen(Qt::DotLine);
//这里的颜色使用了Qt预定义的颜色,可以在帮助中索引Qt::GlobalColor关键字查看
QBrush brush(Qt::blue);
//画笔和画刷可以设置许多样式,使用setStyle()来设置
brush.setStyle(Qt::HorPattern);
painter.setPen(pen);
painter.setBrush(brush);
painter.drawRect(50, 50, 200, 200);
}
弧线
void MainWindow::paintEvent(QPaintEvent *)
{
QRectF rectangle(10.0, 20.0, 80.0, 60.0);//矩形
//画弧线时,角度被分成了十六分之一,就是说,要想为30度,就得是30*16
int startAngle = 30 * 16;//起始角度
int spanAngle = 120 * 16;//跨越度数
QPainter painter(this);
painter.drawArc(rectangle, startAngle, spanAngle);
}
渐变
1.线性渐变
QLinearGradient::QLinearGradient ( const QPointF & start, constQPointF & finalStop )
指定开始点start
和结束点finalStop
。将之间的区域等分,开始点为0.0
,结束点为1.0
。使用QGradient::setColorAt( qreal position, const QColor & color )
插入颜色。
void MainWindow::paintEvent(QPaintEvent *)
{
//线性渐变
QLinearGradient linearGradient(QPointF(40, 190), QPointF(70, 190));
//插入颜色
linearGradient.setColorAt(0, Qt::yellow);
linearGradient.setColorAt(0.5, Qt::red);
linearGradient.setColorAt(1, Qt::green);
//指定渐变区域意外的区域的扩散方式
linearGradient.setSpread(QGradient::ReflectSpread);
//使用渐变作为画刷
QPainter painter(this);
painter.setBrush(linearGradient);
painter.drawRect(10, 20, 90, 40);
}
- 填充方式
setSpread()
设置扩散方式,指明区域以外区域的填充方式:
QGradient::PadSpread
:默认值。使用最近的颜色进行填充
QGradient::RepeatSpread
:重复渐变
QGradient::ReflectSpread
:反射渐变
2. 辐射渐变
QRadialGradient::QRadialGradient( const QPointF & center, qreal radius, const QPointF & focalPoint )
指定圆心center
和半径radius
,这样就确定了一个圆,然后再指定一个焦点focalPoint
。焦点的位置为0,圆环的位置为1,然后在焦点和圆环间插入颜色。
void MainWindow::paintEvent(QPaintEvent *)
{
//辐射渐变
QRadialGradient radialGradient(QPointF(100, 190), 50, QPointF(275, 200));
//插入颜色
radialGradient.setColorAt(0, QColor(255, 255, 100, 150));
radialGradient.setColorAt(1, QColor(0, 0, 0, 50));
//指定渐变区域意外的区域的扩散方式
radialGradient.setSpread(QGradient::RepeatSpread);
//使用渐变作为画刷
QPainter painter(this);
painter.setBrush(radialGradient);
painter.drawEllipse(QPointF(100, 190), 50, 50);
}
- 填充方式
用setSpread()
函数设置渐变区域以外的区域的扩散方式
QGradient::PadSpread
:默认值。使用最近的颜色进行填充
QGradient::RepeatSpread
:重复渐变
QGradient::ReflectSpread
:反射渐变
3. 锥形渐变
QConicalGradient::QConicalGradient ( const QPointF & center,qreal angle )
需要指定中心点center
和一个角度angle
(其值在0到360之间),然后沿逆时针从给定的角度开始环绕中心点插入颜色。这里给定的角度沿逆时针方向开始的位置为0,旋转一圈后为1。
void MainWindow::paintEvent(QPaintEvent *)
{
//锥形渐变
QConicalGradient conicalGradient(QPointF(250, 190), 60);
//插入颜色
conicalGradient.setColorAt(0.2, Qt::cyan);
conicalGradient.setColorAt(0.9, Qt::black);
//使用渐变作为画刷
QPainter painter(this);
painter.setBrush(conicalGradient);
painter.drawEllipse(QPointF(250, 190), 50, 50);
}
- 填充渐变
setSpread()
函数对于锥形渐变没有效果。