Qt-像丝一样滑
来源:互联网 发布:南京大学作家班 知乎 编辑:程序博客网 时间:2024/04/28 12:28
像丝一样滑
在这个例子中,我们介绍画一个pixmap来除去闪烁。我们也会加入一个力量控制。
lcdrange.h包含LCDRange类定义。
lcdrange.cpp包含LCDRange类实现。
cannon.h包含CannonField类定义。
cannon.cpp包含CannonField类实现。
main.cpp包含MyWidget和main。
lcdrange.h
#ifndef LCDRANGE_H#define LCDRANGE_H#include <QVBoxLayout>#include <QWidget>class QSlider;class LCDRange:public QWidget{ Q_OBJECTpublic: LCDRange(QWidget *parent = 0); int showValue() const;//查询滑块的值public slots: void setValue(int);//设置滑块的值 void setRange(int minVal, int maxVal);//设置滑块的范围signals: void valueChanged(int);private: QSlider *slider;};#endif // LCDRANGE_H
lcdrange.cpp
#include "lcdrange.h"#include <QSlider>#include <QLCDNumber>LCDRange::LCDRange(QWidget *parent):QWidget(parent){ QLCDNumber *lcd = new QLCDNumber(2); slider = new QSlider(Qt::Horizontal); slider->setRange(0,99); slider->setValue(0); connect(slider, SIGNAL(valueChanged(int)), lcd, SLOT(display(int))); connect(slider, SIGNAL(valueChanged(int)), SIGNAL(valueChanged(int))); setFocusProxy(slider);//设置这个窗口部件的焦点为slider QVBoxLayout *part = new QVBoxLayout; part->addWidget(lcd); part->addWidget(slider); setLayout(part);}int LCDRange::showValue() const{ return slider->value();}void LCDRange::setValue(int value){ slider->setValue(value);}void LCDRange::setRange(int minVal, int maxVal){ if(minVal<0||maxVal>99||minVal>maxVal) { qWarning("LCDRange::setRange(%d,%d)\n" "\tRange must be 0..99\n" "\tand minVal must not be greater than maxVal", minVal, maxVal); return; } slider->setRange(minVal, maxVal);}
cannon.h
#ifndef CANNON_H#define CANNON_H#include <QWidget>class CannonField:public QWidget{ Q_OBJECTpublic: CannonField(QWidget *parent = 0); QSizePolicy sizePolicy() const; int showAngle() const{return angle;} //显示角度值 int showForce() const{return f;} //显示力量值public slots: void setAngle(int degrees); //接受信号:设置角度值 void setForce(int newton); //接受信号:设置力量值signals: void angleChanged(int); //发送信号:角度值变化 void forceChanged(int); //发送信号:力量值变化protected: void paintEvent(QPaintEvent *); //窗口刷新/重绘private: QRect cannonRect() const; //封装加农炮的矩形 int angle; //角度值 int f; //力量值};#endif // CANNON_H
cannon.cpp
#include "cannon.h"#include "qpaintevent"#include <QPainter>#include <QPixmap>CannonField::CannonField(QWidget *parent):QWidget(parent){ angle = 45; f = 0; setAutoFillBackground(true); setPalette(QPalette(QColor(250,250,200)));}void CannonField::setAngle(int degrees){ if(degrees<5) degrees = 5; if(degrees>70) degrees = 70; if(angle == degrees) return; //如果角度与初始angle相同,返回 angle = degrees; repaint(cannonRect()); //仅重绘加农炮矩形部分 emit angleChanged(angle); //发送angle变化消息}void CannonField::setForce( int newton ){ if(newton < 0) newton = 0; if(f == newton) return; f = newton; emit forceChanged( f );}void CannonField::paintEvent(QPaintEvent *e){ if(!e->rect().intersects(cannonRect())) //判断需要更新的矩形区域和cannonRece()是否相交 return; QRect cr = cannonRect(); //矩形更新 QPixmap pix(cr.size()); //位图双缓冲 pix.fill(this, cr.topLeft()); //fill(widget, ofs:在widget中的偏移):fill the pixmap with the widget's background color or pixmap. QPainter p(&pix); //&pix,在pixmap上画 p.setBrush(Qt::darkGray); p.setPen(Qt::NoPen); p.translate(0, pix.height()-1); //将原点(0,0)变化为(0, pix.height()-1) p.drawPie(QRect(-35, -35, 70, 70), 0, 90*16); //绘制由(x,y,w,h)确定的饼图,开始角度为0,弧长为90*16(四分之一圆),加农炮炮身 p.rotate(-angle); p.drawRect(QRect(33, -4, 15, 8)); //加农炮炮筒 p.end(); p.begin(this);//在屏幕上画 p.drawPixmap(cr.topLeft(), pix); //把pixmap的一部分绘制到屏幕上。像素映射pix,原点就放在cr.topLeft()处。}QRect CannonField::cannonRect() const{//在窗口部件中封装加农炮的矩形,以加农炮圆心为圆心,以(50,50)为(w,h)的矩形 QRect r(0, 0, 50, 50); //(left, top, width, height) r.moveBottomLeft(rect().bottomLeft()); //设置r的左下角为窗口部件自己的左下角 return r;}
main.cpp
#include "mainwindow.h"#include <QApplication>#include <QPushButton>#include <QFont>#include <QSlider>#include <QLCDNumber>#include <QVBoxLayout>#include <QGridLayout>#include "lcdrange.h"#include "cannon.h"class MyWidget:public QWidget{public: MyWidget(QWidget *parent = 0);};MyWidget::MyWidget(QWidget *parent):QWidget(parent){ QPushButton *quit = new QPushButton("&Quit"); quit->setFont(QFont("Times",18,QFont::Bold)); connect(quit,SIGNAL(clicked()),qApp,SLOT(quit())); LCDRange *lcdRange = new LCDRange; lcdRange->setRange(5,70); CannonField *cannonField = new CannonField; connect(lcdRange, SIGNAL(valueChanged(int)), cannonField, SLOT(setAngle(int))); connect(cannonField, SIGNAL(angleChanged(int)), lcdRange, SLOT(setValue(int))); LCDRange *lcdForce = new LCDRange; lcdForce->setRange(10, 50); connect(lcdForce, SIGNAL(valueChanged(int)), cannonField, SLOT(setForce(int))); connect(cannonField, SIGNAL(forceChanged(int)), lcdForce, SLOT(setValue(int))); QGridLayout *grid = new QGridLayout; grid->addWidget(quit, 0, 0); grid->addWidget(cannonField, 1, 1); grid->setColumnStretch(1, 10); QVBoxLayout *leftBox = new QVBoxLayout; grid->addLayout(leftBox, 1, 0); leftBox->addWidget(lcdRange); leftBox->addWidget(lcdForce); lcdRange->setValue(60); lcdForce->setValue(25); lcdRange->setFocus(); //对lcdRange窗口设置键盘焦点 QVBoxLayout *layout = new QVBoxLayout; layout->addLayout(grid); setLayout(layout);}int main(int argc, char *argv[]){ QApplication a(argc, argv); MyWidget w; w.setGeometry( 100, 100, 500, 355 ); w.show(); return a.exec();}
结果截图:
存在问题:
1.为什么有黑色矩形?
2.为什么调节角度时之前的印子没有清除?
与代码 repaint(cannonRect()); 有关吗?教程给的是 repaint(cannonRect(), false);
但是运行有问题:
error: no matching function for call to ‘CannonField::repaint(QRect, bool)’
repaint(cannonRect(),false);
阅读全文
0 0
- Qt-像丝一样滑
- Qt教程10--像丝一样滑
- Qt教程一 —— 第十章:像丝一样滑
- Qt 像VS一样建立解决方案(Qt 子项目)
- 一起来搭建像Qt一样的win32图形框架
- 像Booch一样思考
- 像黑客一样思考
- 像水一样前进
- 像狼一样生存
- 像先辈一样奋斗
- 幸福像花儿一样
- 像男人一样战斗
- 像狼一样战斗
- 像老板一样思考
- 像老板一样思考
- 像风一样自由
- 幸福像花儿一样
- 像树一样活着
- 文件IO lseek
- Linux作业3
- 从txt读取信息然后保存到excel中示例
- 在宿主机上通过NAT模式给kvm虚拟机配置公网IP
- Android OTA系统升级---原理二
- Qt-像丝一样滑
- noip2017题解
- SPI通信过程以及 STM32的SPI特性构架
- 深度学习-BP曲线拟合(预测)
- Linux作业4
- 暴力破解工具hydra(windows)
- opt summary
- 第八章
- 记录自己错误问题