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屏资源-CSDN文库

  • 11
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Qt可以通过使用QComboBox控件来实现下拉菜单。在QComboBox中,可以添加需要显示的选项,并通过信号和槽机制来处理用户选择的选项。例如,在模拟wps中需要一个下拉菜单来选择字体大小,可以创建一个QComboBox控件,将可选的字体大小添加到其中,然后在用户选择完成后,根据用户选择的字体大小来进行相应的处理。 颜色选择器可以使用QColorDialog来实现。QColorDialog是一个对话框窗口,其中包含了各种颜色,并且可以让用户选择颜色。我们可以通过调用其静态方法getColor()来获取用户选择的颜色。例如,在模拟wps中需要用户选择字体颜色,可以通过调用QColorDialog::getColor()方法来让用户选择颜色,然后将选择的颜色应用到文本中。 幕取色器可以使用QScreen类来实现。QScreen类提供了一些用于操作幕的方法,包括获取幕上某个位置的颜色。我们可以使用QScreen::grabWindow()方法来获取幕上指定窗口的截图,然后使用QImage的pixel()方法来获取特定位置的颜色值。例如,在模拟wps中需要用户取色,可以通过获取当前幕上鼠标所在位置的颜色值,并将其应用到文本中。 通过以上的方法,我们可以在Qt中实现模拟wps中的下拉菜单、颜色选择器和幕取色器功能。这些控件和类在Qt中都有相应的文档和示例代码,可以参考官方文档和例子进行具体的实现。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值