Qt C++ 模拟128*64 单色OLED屏

        最近开发的一个项目中,需要用OLED屏幕显示设备参数、控制菜单等,手里没有现成的屏幕,想到采用QT 程序编写一个上位机程序,用来模拟OLED屏的显示;原理很简单,每一个像素是一个点用0和1标识,0标识黑色,1标识白色;128*64的OLED,也就是每行128个像素,一共64行。

       1.  新建一个类OledForm,继承QWidget, 头文件定义如下:

#define OLED_WIDTH 128    //水平像素个数
#define OLED_HEIGHT 64    //垂直像素个数
class OledForm : public QWidget
{
    Q_OBJECT

public:
    explicit OledForm(QWidget *parent = nullptr);
    ~OledForm();
    static OledForm *oled; //静态变量,在构造函数中赋值,指向这个类的实例
    void OLED_DrawPoint(quint8 x,quint8 y,quint8 t);//设置指定像素的值,单色屏因此t的值为0或者1
    uint8_t OLED_GetPoint(quint8 x,quint8 y){return _dram[y][x];}//获取指定像素的值
protected:
    void paintEvent(QPaintEvent *event) override;//重绘事件
    void resizeEvent(QResizeEvent *resizeEvent) override;//窗口大小重置事件
    void mousePressEvent(QMouseEvent *event);//鼠标按下事件
    void mouseReleaseEvent(QMouseEvent *event);//鼠标抬起事件
    void mouseMoveEvent(QMouseEvent *event);//鼠标移动事件
    QPoint press_point,move_point;//保存按下或者移动时,鼠标的坐标位置
    uint8_t _dram[OLED_HEIGHT][OLED_WIDTH];//二维数组,保存屏幕像素点的值,0或者1 
    int point_size;//像素大小
    int point_space;//每个像素的间隔
    int _width,_height;//窗口的宽和高,
    double factor;//缩窗口放系数
    int rect_w,rect_h;
    bool is_draw_rect;
signals:
    void reportSelectRect(QRect rect);
private:

    void DrawRect(QPainter *painter,int x,int y);
    Ui::OledForm *ui;
};

2.实现头文件中所定义的函数

#include "oledform.h"
#include "ui_oledform.h"
#include <QPainter>
#include <QtDebug>
#include <QMouseEvent>
OledForm * OledForm::oled = nullptr;

OledForm::OledForm(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::OledForm),
    is_draw_rect(false)
{
    ui->setupUi(this);
    _width = geometry().width();
    _height = geometry().height();
    for(int x = 0; x <OLED_WIDTH; x++){
        for(int y = 0; y < OLED_HEIGHT; y++){
             _dram[y][x] = 0;
        }
    }
    point_size = 10;
    point_space = 1;
    oled = this;
    _height = OLED_HEIGHT * (point_space+point_size);
    _width  = OLED_WIDTH  * (point_space+point_size);
    if(geometry().height() /_height > geometry().width()/_width){
        factor = (double)geometry().width()/(double)_width;
    }else{
        factor = (double)geometry().height() /(double)_height;
    }

    //setGeometry(0,0,OLED_WIDTH * (point_space+point_size),OLED_HEIGHT * (point_space+point_size));

}

OledForm::~OledForm()
{
    delete ui;
}
void OledForm::DrawRect(QPainter *painter,int x,int y)
{
    painter->setBrush(QBrush(Qt::blue));
    painter->drawRect(x * (point_space+point_size),y * (point_space + point_size),point_size ,point_size );

}
void OledForm::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    painter.save();
    painter.setRenderHint(QPainter::Antialiasing);

    double f ;
    if(width()/height() < 2){
        f =  (double)height()/(double)_height;
    }else{
        f =  (double)width()/(double)_width;
    }

    painter.fillRect(0, 0,width(),height(), QBrush(Qt::lightGray));

    painter.scale( (double)factor*f, (double)factor*f);

    for(int x = 0; x <OLED_WIDTH; x++){
        for(int y = 0; y < OLED_HEIGHT; y++){
             if(_dram[y][x])
                DrawRect(&painter,x,y);
        }
    }
    painter.restore();
    if(is_draw_rect){
        painter.drawRect(press_point.x(),press_point.y(),rect_w,rect_h);
    }
    {
     painter.drawLine(move_point.x(),0,move_point.x(),height());
     painter.drawLine(0,move_point.y(),width(),move_point.y());
    }
}
void OledForm::mousePressEvent(QMouseEvent *event)
{
   QPoint point =  event->pos();
   qDebug()<<point;
   double f ;
   if(width()/height() < 2){
       f =  (double)height()/(double)_height;
   }else{
       f =  (double)width()/(double)_width;
   }
   move_point = event->pos();
   press_point = event->pos();
   update();
   //qDebug()<<"x:" << point.x()/((point_space+point_size)*((double)factor*f));
  // qDebug()<<"y:" << point.y()/((point_space+point_size)*((double)factor*f));

}
void OledForm::mouseReleaseEvent(QMouseEvent *event)
{
    double f ;
    int x,y, t_widht,t_height;
    is_draw_rect = false;
    if(width()/height() < 2){
        f =  (double)height()/(double)_height;
    }else{
        f =  (double)width()/(double)_width;
    }
    x = press_point.x()/((point_space+point_size)*((double)factor*f));
    y = press_point.y()/((point_space+point_size)*((double)factor*f));
    t_widht  = rect_w /((point_space+point_size)*((double)factor*f));
    t_height = rect_h /((point_space+point_size)*((double)factor*f));
    reportSelectRect(QRect(x,y,t_widht + 1,t_height + 1));
    update();
}
void OledForm::mouseMoveEvent(QMouseEvent *event)
{
    move_point = event->pos();
    if (QApplication::mouseButtons() & Qt::LeftButton) {
        QPoint point =  event->pos();
        rect_w =  point.x() - press_point.x() + 1;
        rect_h =  point.y() - press_point.y() + 1;
        move_point = event->pos();
        is_draw_rect = true;
        //update();
    }
     update();
    {
        //move_point = event->pos();
       // qDebug()<<move_point;
        //update();
    }
}
 void OledForm::OLED_DrawPoint(quint8 x,quint8 y,quint8 t)
 {
    _dram[y][x] = t;
 }
void OledForm::resizeEvent(QResizeEvent *resizeEvent)
{



}

3.在MainWidow类中,实现对按键的检测功能

void MainWindow::keyPressEvent(QKeyEvent *event)
{
    switch (event->key()) {
        case Qt::Key_Up:
            key_up_sw_event(nullptr);
            break;
        case Qt::Key_Down:
            key_down_sw_event(nullptr);
            break;
        case Qt::Key_Left:
            key_left_sw_event(nullptr);
            break;
        case Qt::Key_Right:
            key_rigth_sw_event(nullptr);
            break;
        case Qt::Key_Space:
            key_ok_sw_event(nullptr);
        default:
            QWidget::keyPressEvent(event);
    }
}

最终的运行效果如下所示:

完整的工程路径:

        【免费】QtC++模拟OLED屏资源-优快云文库

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值