找回密码
 立即注册
收起左侧

点阵编辑器

5
回复
11193
查看
[复制链接]
累计签到:17 天
连续签到:1 天
来源: 2013-9-8 21:58:22 显示全部楼层 |阅读模式
版权声明

该文章原创于Qter开源社区www.qter.org),作者lxdlbs371,转载请注明出处!


首先,该软件并不完善,中间因需求打断了。所以只写了删除操作,其他操作还没有添加,看明白的朋友有空可以添加。


一:程序截图:
(1) 输入字母和数字,以点阵形式显示,有光标。



(2) 移动光标,删除其中的字(现在只能删除,其他操作没有写,程序中已经提供了API)



二:软件分析:
(1) 架构分析




(2)图元分析





(三)代码概略
(1)逻辑层:一些重要的数据结构
  1. //矩阵方位数据结构  
  2. QPoint m_MatrixPoint; //x 为行号,y为列号 从0行0列开始  
  3. //! 控制全局所有图元的区域  
  4. QList < QList<QRect> >m_Matrix;  
  5. //! 记录光标所有的位置,主要是为了根据当前光标返回所在的行号和列号  
  6. QList < QList<QPoint> > m_cursorMatrix;  
  7. //! 记录该图元是否是可以改变,x:行号 y:列号  
  8. QList < QPoint > m_changeAreaList;  
  9.    
  10. QRect m_deleteArea; //删除区域,根据当前光标找到前一个位置,然后返回该区域  
  11. QRect m_insertArea; //插入区域:根据当前光标进行插入的区域,和m_rowEndArea共用  
  12. QRect m_EnterArea; //换行区域:每次都到下一行的起始断,并且修改矩阵,和m_rowListArea共用  
  13. QRect m_rowEndArea; //当前行某一列到该行行末的区域  
  14. QRect m_rowListArea; //换行前,下一行到末尾所有的区域  
  15. QList<QRect> m_rowAreaList;
复制代码


(2)数据层:比较简单,就是实际画布
  1. void DataImage::setImage(QImage dataImage)  
  2. {  
  3.          this->m_dataImage = dataImage;  
  4.          this->update();  
  5. }
复制代码


(3)背景层: 代码里是视图层,但逻辑上我把它分成背景,主要是画光标和网格
  1. /*! ******************************************
  2. *  视图层:从数据image获取数据后,根据其像素点分别画在视图上
  3. *******************************************/
  4. /*!
  5.   * 画面大小
  6.   */
  7. void EditScene::initSize(QGraphicsView *view, int iWidth, int iHeight )
  8. {
  9.     this->initColor();
  10.     this->m_iCustXCnt = iWidth;
  11.     this->m_iCustYCnt = iHeight;
  12.     this->m_dataImage = QImage( iWidth, iHeight , QImage::Format_Mono );

  13.     this->m_dataImage.fill( m_backColor.rgb() );

  14.     this->m_iSize = view->size().height()/this->m_iCustYCnt;
  15. //    view->setGeometry( view->geometry().x(), view->geometry().y(),
  16. //                       WIDTH, HEIGHT*m_iSize +SPACE);

  17.     this->setSceneRect(0, 0, iWidth*m_iSize, iHeight*m_iSize);
  18.     qDebug() << m_iCustXCnt*m_iSize<< m_iCustYCnt*m_iSize <<__FILE__<<__LINE__;
  19.     m_backImage =  QImage( m_iCustXCnt*m_iSize, m_iCustYCnt*m_iSize, QImage::Format_Mono );
  20.     m_backImage.fill( m_backColor.rgb() );
  21. }


  22. /*!
  23.   * 初始化颜色
  24.   */
  25. void EditScene::initColor()
  26. {
  27.     m_backLineColor  = Qt::darkYellow;     //网格颜色
  28.     m_pointColor = Qt::black;             //画圆
  29.     m_backColor  = Qt::white;             //背景白色
  30. }

  31. /*!
  32.   * 画网格
  33.   */
  34. void EditScene::setGrid(bool enable)
  35. {

  36.     qDebug()  << m_iSize << m_iCustXCnt<< m_iCustYCnt <<this->height()<< this->width()
  37.             <<m_iCustXCnt*m_iSize<<m_iCustYCnt*m_iSize<<__FILE__<<__LINE__;
  38.     QPainter painter( &m_backImage );

  39.     if ( enable ) {
  40.         QPen pen(this->m_backLineColor, 0); //虚线的颜色
  41.         pen.setStyle( Qt::DotLine);  //虚线的类型
  42.         painter.setPen( pen );

  43.         for( int i = 1; i < this->m_iCustXCnt; ++i ) {
  44.             int x = m_iSize*i;
  45.             painter.drawLine( x, 0, x, this->height() );
  46.         }

  47.         for ( int j = 1; j < this->m_iCustYCnt; ++j ) {
  48.             int y = m_iSize*j;
  49.             painter.drawLine(0, y, this->width(), y );
  50.         }
  51.     }
  52. m_backImage.save("/home/lbs/1.bmp");
  53.     this->setBackgroundBrush( this->m_backImage );

  54. }
复制代码


(4)视图层:根据像素画点
  1. /*!
  2. *判断是否画点
  3. */
  4. bool EditScene::isDrawPoint( int icustx,int icusty )
  5. {
  6.     //int gray = DataImage.pixel( QPoint(icustx,icusty) );
  7.     int gray = qGray( this->m_dataImage.pixel(QPoint(icustx,icusty)) );

  8.     if( gray == 0 ){
  9.         return true;
  10.     }else{
  11.         return false;
  12.     }
  13. }

  14. /*!
  15.   * 清除某点
  16.   */
  17. void EditScene::ClearPoint( int icustx, int icusty )
  18. {
  19.     QPainter painter( &m_backImage );

  20.     painter.setPen( QPen( Qt::transparent, 0 ) );
  21.     painter.setBrush( QBrush( m_backColor, Qt::SolidPattern ) );
  22.     painter.drawRect( icustx*m_iSize+1, icusty*m_iSize+1 , m_iSize-2, m_iSize-2 );
  23.     this->setBackgroundBrush( m_backImage );

  24.     ClearDataImagePoint( icustx, icusty );
  25. }

  26. /*!
  27.   * 清除数据图像上的某点
  28.   */
  29. void EditScene::ClearDataImagePoint( int icustx ,int icusty )
  30. {
  31.     this->m_dataImage.setPixel( icustx, icusty , 1 );
  32. }
复制代码


(5)动作事件:接受键盘动作
  1. /*! ******************************************
  2. * 事件层:接收命令,下发动作
  3. *******************************************/  
  4. void EditScene::keyPressEvent(QKeyEvent *event)  
  5. {  
  6. switch( event->key() ) {  
  7. //操作  
  8. case Qt::Key_Up:  
  9. emit this->sendCursorMove( Location::Up);  
  10. break;  
  11. 。。。。。。。。。  
  12. }  
  13. /*!
  14. * 插入操作
  15.   */
  16. void EditScene::insertOpeSlot()
  17. {
  18.     emit
  19. this->sendCursorMove( Location::Insert );
  20. }

  21. /*!
  22.   *
  23. 根据按键输入不一样的字符
  24.   */
  25. void EditScene::setKeyText(QString minStr,
  26. QString maxStr)
  27. {
  28.     QString sendStr;
  29.     if (
  30. this->m_capsEnabel ) {
  31.     //! 大写数据
  32.       sendStr = maxStr;

  33.     }else {
  34.     //!  小写数据
  35.        sendStr =  minStr;
  36.     }
  37.   
  38.   emit this->sendText( sendStr );

  39. }

  40. /*!
  41.   * 重绘
  42.   
  43. */
  44. void EditScene::Redraw(QRect sourceArea ,QPoint newTopLeft)
  45. {


  46.     qDebug() <<sourceArea<<
  47. newTopLeft<<__FILE__<<__LINE__;
  48.     QImage m_oldImage =
  49. m_dataImage.copy( sourceArea );
  50.     this->cleanRect( sourceArea );

  51.     m_cursorTopLeft = newTopLeft;

  52.     //画点
  53.     if(
  54. !m_oldImage.isNull() ){
  55.         for( int i = 0; i <
  56. m_oldImage.height(); ++i ){
  57.             for ( int j = 0; j <
  58. m_oldImage.width(); ++j ){
  59.                 int gray = qGray(
  60. m_oldImage.pixel( QPoint(j,i) ) );
  61.                 if( gray == 0 ){

  62.                     //! 要加入 光标的位置 m_cursorTopLeft
  63.                   
  64. DrawPoint(  m_cursorTopLeft.x()+ j,m_cursorTopLeft.y()+ i );
  65.       
  66.          }
  67.             }
  68.         }
  69.     }
  70.    
  71. this->m_displayerImage->setImage( this->m_dataImage);

  72. }

  73. /*!

  74.   * 加载镜像,并提出灰度,并画点
  75.   */
  76. void EditScene::LoadPointByImage( QImage *
  77. img )
  78. {
  79.     if( !img->isNull() ){
  80.         for( int i = 0; i
  81. < img->height(); ++i ){
  82.             for ( int j = 0; j <
  83. img->width(); ++j ){
  84.                 int gray = qGray(
  85. img->pixel( QPoint(j,i) ) );
  86.                 if( gray == 0 ){

  87.                    //! 要加入 光标的位置 m_cursorTopLeft
  88.                     
  89. DrawPoint(  m_cursorTopLeft.x()+ j,m_cursorTopLeft.y()+ i );
  90.         
  91.         }
  92.             }
  93.         }
  94.     }
  95.    
  96. this->m_displayerImage->setImage( this->m_dataImage);
  97.    
  98. //移动光标
  99.     emit this->sendNewUnit();
  100.     emit
  101. this->sendCursorMove( Location::Right);

  102. }
  103. /*!
  104.   *
  105. 获取清除区域范围
  106.   */
  107. void EditScene::cleanRect(QRect rect)
  108. {
  109.    
  110. //移动光标
  111. //    emit this->sendCursorMove( Location::Left);
  112. //   
  113. QSize cleanSize = rect.size();
  114. //    QImage cleanImage =
  115. this->m_dataImage.scaled(
  116. cleanSize,Qt::KeepAspectRatio,Qt::FastTransformation);
  117.    
  118. m_cleanTopLeft = rect.topLeft();
  119.     qDebug() << rect.topLeft()
  120. <<__FILE__<<__LINE__;
  121.     this->cleanPointByImage(
  122. &m_dataImage.copy( rect ) );

  123. }

  124. /*!
  125.   * 清除区域内所有点

  126.   */
  127. void EditScene::cleanPointByImage(QImage  *img)
  128. {

  129.    
  130. if( !img->isNull() ){
  131.         for( int i = 0; i <
  132. img->height(); ++i ){
  133.             for ( int j = 0; j <
  134. img->width(); ++j ){
  135.                 int gray = qGray(
  136. img->pixel( QPoint(j,i) ) );
  137.                 if( gray == 0 ){

  138.                    //! 要加入 光标的位置 m_cursorTopLeft

  139.                
  140.     this->ClearPoint(j+m_cleanTopLeft.x(),i+ m_cleanTopLeft.y());

  141.                 }
  142.             }
  143.         }
  144.     }
  145.    
  146. this->m_displayerImage->setImage( this->m_dataImage);

  147. }
复制代码

代码下载请到下面地址:



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

累计签到:1568 天
连续签到:1 天
2013-9-8 22:32:06 显示全部楼层
很实用的教程。希望大家可以继续完善,把点阵这一块全部搞定。
回复 支持 反对

使用道具 举报

累计签到:7 天
连续签到:1 天
2013-12-15 16:31:56 显示全部楼层
很好很强大,支持!绝对顶!
回复 支持 反对

使用道具 举报

累计签到:18 天
连续签到:1 天
2014-9-10 17:59:26 显示全部楼层
楼主,您好!我下载您的原码编译后出现下面问题,我用的是QT5.
In member function 'void EditScene::cleanRect(QRect)':
错误:taking address of temporary [-fpermissive]

这个是什么原因?该怎么解决。
回复 支持 反对

使用道具 举报

累计签到:1 天
连续签到:1 天
2014-12-4 09:45:10 显示全部楼层
新来报到,谢谢,支持。。。
回复 支持 反对

使用道具 举报

累计签到:1 天
连续签到:1 天
2017-6-26 14:07:32 显示全部楼层
lpdpzc 发表于 2014-12-4 09:45
新来报到,谢谢,支持。。。



新来报到,谢谢,支持。。。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

公告
可以关注我们的微信公众号yafeilinux_friends获取最新动态,或者加入QQ会员群进行交流:190741849、186601429(已满) 我知道了