10426|7

603

帖子

1

TA的资源

纯净的硅(中级)

楼主
 

做自己的QT图形应用 [复制链接]

做自己的QT图形应用
参与HELPER2416开发板助学计划

原计划研究一下驱动的,不过后来发现,板子所带的材料,里面已经有比较完善的驱动了,可以做做更难的事,不过掂量一下时间,果断决定,做做QT开发吧。
其实楼主从来没有做过QT的程序,趁这个机会学习一下,这样比较好。

所以打开虚拟机,从头开始,新建一个QT工程。
总得巧立名目建立工程……唉,楼主就喜欢马里奥,而且是现成的逻辑,做个移植吧。
建立工程,并把已有的代码加入到工程里。

接着呢,我的处理是这样的去掉了界面的菜单栏、工具栏和状态栏,这些都是在UI设计器里可以做到的。
于是我的应用程序,只剩下一个空荡荡的窗体了。

然后,基本就全指望代码啦。首先是和界面有关的内容。
我不想显示标题栏,希望我的窗体是全屏效果的,所以需要这些代码:
  1.     ScrWidth = 480;
  2.     ScrHeight = 272;
  3.     this->setFixedSize(ScrWidth,ScrHeight);
  4.     this->setWindowFlags(Qt::FramelessWindowHint);
复制代码

而没有了菜单栏,就需要我们自己去实现一个弹出式的菜单:
  1.     menu = new QMenu(this);
  2.     QAction *act = new QAction("Open...", this);
  3.     connect(act, SIGNAL(activated()) , this, SLOT( on_actionOpen_triggered() ) );
  4.     menu->addAction(act);
  5.     act = new QAction("Exit", this);
  6.     connect(act, SIGNAL(activated()) , this, SLOT( on_actionExit_triggered() ) );
  7.     menu->addAction(act);
复制代码

当点击屏幕的时候,就弹出菜单,需要重载继承来的函数:
  1. void MainWindow::mouseReleaseEvent(QMouseEvent *event)
  2. {
  3.     menu->exec(this->mapToGlobal(event->pos()));
  4. }
复制代码

当然,不要忘记了写菜单处理的函数。

在模拟器的帧扫描期间,要把游戏画面画在屏幕上,这个方法太多了,我找来找去,决定用这样的办法:把游戏画面内容拷贝到内存图片里,然后把图片按比例贴在窗体上:
  1. extern
  2. void InfoNES_LoadFrame()
  3. {
  4.     PIXEL *pfb = (PIXEL*)image->bits();
  5.     for(int i=0;i<224 * 256;i++)
  6.     {
  7.         pfb[i] = WorkFrame[i];
  8.     }

  9.     QCoreApplication::postEvent(m_pWindow, new QEvent(CustomEvent_Login));

  10.     qApp->processEvents();
  11. }
复制代码

可以看到上面的代码,我把画面数据复制到内存中去了,然后给主窗体发了消息,当主窗体接到消息,就来贴图:
  1.     QPainter p;
  2.     QMatrix pm;

  3.     //设置放大倍数
  4.     pm.scale(480.0/image->width(), 272.0/image->height());

  5.     p.begin(this);
  6.     p.setWorldMatrix(pm);
  7.     p.drawImage(0,0,*image);
  8.     //p.drawPixmap(0, 0, *image);
  9.     p.end();
复制代码

楼主也是后来听说QImage很好用……原来用QPixmap,说实话找了很多手册和说明,没看明白怎么用,各种实验各种失败。

于是这个应用程序还要涉及到自定义事件,重载继承来的函数:

  1. void MainWindow::customEvent(QEvent *event)
  2. {
  3.     this->repaint();
  4. }
复制代码

如果你看到这里,需要补充一句,楼主C++不太擅长,在网上查了好久,找了好多资料,大部分资料只告诉你要重载某某函数,实际写的时候呢,一定要记得在头文件里MainWindow的类定义中也加上重载的函数声明,这句话从来没有人提醒楼主,楼主自己摸索了好久,才反应过来需要这样弄。平时接触到的面向对象也是一门语言一个情况啊,让我一开始就有在头文件里声明的意识……楼主做不到啊……

至于被楼主删掉的原来的菜单如何添加响应,在界面设计器里就可以可视化地实现啦,很简单的。我们这里不用默认的菜单,而弹出菜单也就是直接写上代码就好了。
  1. void MainWindow::on_actionOpen_triggered()
  2. {
  3.     QFileDialog dlg(this,"open rom file");
  4.     dlg.resize(ScrWidth, ScrHeight);
  5.     dlg.setAcceptMode(QFileDialog::AcceptOpen);
  6.     dlg.setFileMode(QFileDialog::ExistingFile);
  7.     dlg.setNameFilter("All file(*.*);Nes file(*.nes)");
  8.     dlg.showMaximized();

  9.     delete image;
  10.     image = new QImage(256, 224, QImage::Format_RGB16);

  11.     if(dlg.exec() == QFileDialog::Accepted){
  12.         QString path = dlg.selectedFiles().first();
  13.         //QMessageBox::information(NULL, tr("Path"), tr("You selected ") + path);

  14.         /**/
  15.         if(InfoNES_Load(path.toStdString().data()) == 0)
  16.         {
  17.             running = 1;
  18.             QtConcurrent::run(thread_nes,this);
  19.         }
  20.         /**/

  21.     }  else {
  22.         QMessageBox::information(NULL, tr("Path"), tr("You didn't select any files."));
  23.     }
  24. }

  25. void MainWindow::on_actionExit_triggered()
  26. {
  27.     QApplication* app;
  28.     app->quit();
  29. }
复制代码

从上面的代码也可以看到,由于模拟器的核心是一个死循环,为了界面还能工作,楼主决定使用一个单独的线程来跑模拟器核心。核心线程体的函数如下:
  1. void thread_nes(QObject *win)

  2. {
  3.     m_pWindow = win;
  4.     InfoNES_Main();
  5. }
复制代码

对于在图形界面应用开发的重点内容,应该是都在上面了。剩下的就是关于模拟器内核的有关处理了。详细可以参考我以前发的有关移植InfoNES的文章,就不在这里赘述了。

具体内容还是留一份工程源码吧,由于这只是半成品,所以以上的全部内容,再加上模拟器需要的平台相关的处理,都被写到了MainWindow的原文件中,并且还有许多调试用的痕迹。这些痕迹实在是舍不得删了,有一些甚至反映了我学习的过程,考虑再三保留下来一起打包了。

InfoNES.zip (9.96 MB, 下载次数: 207)

再来看看关于程序运行。请参考之前一位童鞋的帖子——Helper2416助学: 玩转ARM应用程序开发从QT开始https://bbs.eeworld.com.cn/thread-442619-1-1.html

一般情况下应该都是可以成功的,InfoNES编译得到的InfoNES可执行程序,我都是复制到根目录下运行,
最后运行起来的话嘛……

哇,花屏了!嘿嘿,因为楼主比较懒嘛,一开始并没有初始化贴在屏幕上的QImage。没事的,尽管触摸屏幕好啦!

这里,在Open的命令响应处理里面,是打开文件的对话框,我们把NES的游戏文件也复制到板上,就可以直接打开啦

比如打开马里奥大叔的游戏……

哦,忘记了,现在还没有实现手柄控制,所以只能看看DEMO了,按照这个比例,扁扁的大叔有点丑

再欣赏欣赏魂斗罗,看起来没有太大问题。

当然了,到目前为止,这个程序还没有达到理想的状态,站在学习的角度来说,一些小问题就不重要了,现在一个很重要的问题,就是游戏过程中对于操作的响应不够及时,如何提高对用户的响应效率,这其实是图形界面程序开发的一个重要问题,楼主还需要继续努力呢。

论坛ID:sjtitr
提交时间:2014.08.24

最新回复

太神了,感谢楼主分享!!!  详情 回复 发表于 2016-2-27 19:59

赞赏

1

查看全部赞赏

点赞 关注(2)

回复
举报

554

帖子

0

TA的资源

版主

沙发
 
这又是在移植游戏吗?太强大了!真是人多力量大啊!
 
个人签名My dreams will go on...
http://www.jyxtec.com
 

回复

554

帖子

0

TA的资源

版主

板凳
 
本帖最后由 spacexplorer 于 2014-8-24 21:38 编辑

好象缺少nes文件啊?这里上传一个超级魂斗罗! super.zip (141.72 KB, 下载次数: 18)

 
个人签名My dreams will go on...
http://www.jyxtec.com
 
 

回复

109

帖子

0

TA的资源

一粒金砂(中级)

4
 
So cool!
 
 
 

回复

1488

帖子

2

TA的资源

纯净的硅(中级)

5
 
顶一个 最近公司产品升级 天天拉线调试 没有时间玩啊
 
个人签名专业从事于在线监测振动、转速、轴振动、位移等,设备管理及故障检测振动诊断系统在线监测点巡检系统-现场动平衡仪-测振仪、便携式测振仪
 
 

回复

70

帖子

0

TA的资源

一粒金砂(中级)

6
 
     好东西,楼主这是自己做PSP的节奏啊,太吊炸天了。 我喜欢。 顶一下。
 
个人签名线性模组 直线导轨 三轴运动平台厂家 http://www.vavsz.com
 
 

回复

13

帖子

0

TA的资源

一粒金砂(初级)

7
 
游戏移植啊  楼主太帅了  我现在才刚刚入门QT
 
 
 

回复

12

帖子

0

TA的资源

一粒金砂(初级)

8
 
太神了,感谢楼主分享!!!
 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表