
可以通过QGLWidget运行opengl。QGLWidget继承QWidget,能够直接在里面调用opengl的接口。这个在qt文档里有具体说
明,也有相关例子,所以不赘述了。但是无法在正式软件里面执行,为什么?因为正式软件是用QGraphicsScene这个场景类 *** 作和 *** 作一切
item,而用QGraphicsView将其显示出来,而每一个item都是QGraphicsItem的子类。QGLWidget并不是QGraphicsItem类,我曾经尝试用普通的QWidget类那样,通过proxy来加进QGraphicsItem,但是没有成功。或许有方法,但是没有找到。
于是我放弃了用QGLWidget来 *** 作opengl的打算,寻找直接在QGraphicsItem中 *** 作opengl的方法。通过查看文档和示例代码,找到了这个方法:
1 往qt工程文件里添加opengl以及对应的lib。
2
对QGraphicsView进行一个三维对话框的指定,代码如下:
QGLWidget *widget = new
QGLWidget(QGLFormat(QGL::SampleBuffers))
widget->makeCurrent()
QGraphicsView
view
view.setViewport(widget)
上述代码告诉了 QGraphicsView 类当前绘制的对象是支持opengl的。于是所有的场景中的item都将绘制到widget 上。
3
写一个QGraphicsItem的继承类,特别要重写paint函数。代码如下:
void XXX::paint(QPainter
*painter, const QStyleOptionGraphicsItem *option, QWidget
*widget)
{
painter->beginNativePainting()
glColor3f(0.5,1.0,0.2)
glBegin(GL_TRIANGLES)
glVertex3f(100.0,100.0,-100.0)
glVertex3f(150.0, 100.0,
-100.0)
glVertex3f(100.0, 150.0,
-100.0)
glEnd()
painter->endNativePainting()
}
上面这个函数主要是用opengl接口绘制了一个三角形。记住,在opengl绘制之前一定要执行painter->beginNativePainting()以及painter->endNativePainting()这两个语句。
QGraphicsScene、
QGraphicsView和QGraphicsItem的关系可以查阅相关文档,也不赘述了。
不过我按照这个方式画的三角形,怎么也在窗口上显示不出来,找了半天才发现问题在这个函数上QGraphicsItem::boundingRect()。这个函数是
干什么用的呢?主要用来返回该item的初始化大小,这个大小不会轻易改变,后续的改变都可以通过矩阵来完成,但是初始大小是不变的。QGraphicsView通过这个矩形来判断当前item是不是需要重绘,如果在重绘区外,则不调用重绘函数了。同时碰撞检测之类,也可以用这个矩形来判断。原来,item本身的矩阵外包框不对,所以才导致了重回不出来,改过来就正确了。
上面说的很潦草,具体怎么改的步骤就不说了。要想正确的绘制,必须得弄清楚坐标系的关系,QGraphicsScene、QGraphicsView以及QGraphicsItem这三个坐标系到底是什么关系。我看了文档,也自己进行了测试,但是感觉文档和测试的结果有些出入。具体出入不说了。说一下自己得心的吧。
先说明:涉及到一切大小和长度,都是像素大小,至少我测试的结果是这样的。
在建立QGraphicsScene
对象的时候,有一个构造函数是矩形,这个矩形是什么含义呢?经过测试,发现这个矩形并没有指定d出窗口的位置,比如,我把矩形的左上角点指定为
-1000,-1000,显示的位置和1000,1000是一样的,而长度则正确指定了(当然,可能会有滚动条)。所以,这个矩形的左上角点并不是显示的
窗口的位置,而是它在逻辑上的左上角点。我们显示一切item,都是以这个逻辑上的坐标系为准来绘制的。比如,左上角点是-1000,-1000,而
item的位置在-500,-500,则这个-500,-500相当于在显示窗口的左上角往下各加500个像素的坐标的位置。
那么 QGraphicsItem的boundingRect是什么意思呢?返回的是什么大小?是以什么坐标系显示的大小?首先,这个大小肯定是以像素为单位的,其次,这个矩形的坐标是以QGraphicsScene的逻辑坐标为准的。当然这个大小是没有任何矩阵叠加的大小。有了矩阵叠加后,实际的矩形可能会发生变化。假如在boundingRect中指定矩形的左上角为100,100,那么最终体现的位置则是QGraphicsScene逻辑坐标100,100的位置,如果QGraphicsScene的左上角点已经指定为-1000,-1000,那么这个位置实际上就是离窗口左上角点1100,1100的位置(由于有滚动条,所以也不一定是这个长度。)
那么在QGraphicsItem的paint函数中进行了opengl绘制用的是什么坐标呢?其实用的也是QGraphicsScene
的逻辑坐标。如上面的例子,绘制的直角三角形直角顶点是0,0,那么显示的位置就是距离显示窗口左上角点1000,1000的位置。不过opengl的所
有绘制都是没有矩阵叠加的基础上,如果用矩阵叠加,则显示的位置肯定和指定的有区别了。比如,我用setPos强制指定一个位置,这个位置将和opengl绘图坐标相叠加,最后显示到窗口上。我推测setPos其实是改变了矩阵,是一个平移矩阵。
1、设计gui图形界面,创建一button,并在clicked下添加代码第一种方法(50行)是调用linux C函数库中的system(const char *string)
第二种方法(51行)和第三种方法(53 54行)是调QT里的函数
需要说明的时,上面三种方法都是可以的,但前两种方法会阻塞进程,直到smplayer程序结束,而第三种方法则不会阻塞进程,可以多任务运行。
还有,我们知道qt在运行的时候,要启动qws(qtwindows server),如果用前面两种方法,则smplayer运行的时候,要新开启一个qws,否则不能运行;而用第三种方法,则不需要再开启qws,它和HelloQt4共用一个qws,这样,在一个窗口里可以看到这两个程序。
2、新建运行脚本,用来启动smplayer播放器
在上一步中,qt程序执行了
/opt/run_smplayer脚本,但这个脚本是不存在的,我们要新建它,打开开发板的/opt目录,新建一个run_smplayer文件,添加如下内容
#!/bin/sh
#测试用
#cd /opt/
#rm qt_create/
-rf
#sleep 3
#mkdir qt_create
#cd qt_create
#mkdir qt_create1
#cd qt_create1
#mkdir qt_create2
#cd qt_create2
#mkdir ok
#直接调用mplayer播放sdcard里的gq.avi文件
#cd /usr/local/smplayer/bin
#./mplayer /sdcard/gq.avi
#启动友善的smplayer
cd /usr/local/smplayer/bin
./smplayer
3、修改smplayer文件
在友善的根文件系统中,/user/lical/smplayer/bin目录中的smplayer脚本是有问题的,如果直接运行它,会出现鼠标和触摸屏
不能使用的情况,我们要将/bin目录下的smplayer脚本复制过来,并将最后两行中的qws去掉。(前面提到过的,我们要多任务运行,不需要再开一
个qws)
export HOME=/root
cd /usr/local/smplayer/
exe__c ./smplayer #-qws 1>/dev/null
2>/dev/null
// 此处有屏蔽字,真实没有下划线
#hotplug
4、修改rcS文件,使之开机就运行HelloQt4i程序
rcS文件如下:
#!
/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin:
runlevel=S
prevlevel=N
umask 022
export PATH runlevel prevlevel
#
#Trap CTRL-C &c
only in
this shell so we
can interrupt subprocesses.
#
trap ":" INT QUIT TSTP
/bin/hostname Crt
[ -e /proc/1 ]
||
/bin/mount -n -t proc none
/proc
[ -e /sys/class ] ||
/bin/mount -n -t sysfs none /sys
[ -e /dev/tty ]
||
/bin/mount
-t ramfs
none /dev
/bin/mount -n -t usbfs none
/proc/bus/usb
echo /sbin/mdev >
/proc/sys/kernel/hotplug
/sbin/mdev -s
/bin/hotplug
# mounting file system specified in
/etc/fstab
mkdir -p /dev/pts
mkdir -p /dev/shm
/bin/mount -n -t devpts none
/dev/pts -o mode=0622
/bin/mount -n -t tmpfs tmpfs /dev/shm
/bin/mount
-n
-t ramfs
none /tmp
/bin/mount -n -t ramfs none
/var
mkdir -p /var/empty
mkdir -p /var/log
mkdir -p /var/lock
mkdir -p /var/run
mkdir -p /var/tmp
/sbin/hwclock -s
syslogd
/etc/rc.d/init.d/netd start
echo "
"
>
/dev/tty1
echo "Starting networking..."
>
/dev/tty1
sleep 1
/etc/rc.d/init.d/httpd start
echo "
"
>
/dev/tty1
echo "Starting web server..."
>
/dev/tty1
sleep 1
/etc/rc.d/init.d/leds start
echo "
"
>
/dev/tty1
echo "Starting leds service..."
>
/dev/tty1
echo "
"
sleep 1
echo "
"
>
/dev/tty1
/etc/rc.d/init.d/alsaconf start
echo "Loading sound card config..."
>
/dev/tty1
echo "
"
/sbin/ifconfig lo 127.0.0.1
/etc/init.d/ifconfig-eth0
#/bin/qt4 &
#echo "
"
>
/dev/tty1
#echo "Starting Qt4 Applications, please
waiting..."
>
/dev/tty1
#/bin/smplayer &
#echo "
"
>
/dev/tty1
#echo "Starting smplayer Applications, please
waiting..."
>
/dev/tty1
/bin/hello_qt4app &
echo "
"
>
/dev/tty1
echo "Starting
hello_qt4 Applications, please
waiting..."
>
/dev/tty1
hello_qt4app脚本如下:
#!/bin/sh
rm /root/.config/
-rf
rm /root/.mplayer/
-rf
if [ -e /etc/friendlyarm-ts-input.conf ] then
. /etc/friendlyarm-ts-input.conf
fi
true
${TSLIB_TSDEVICE:=/dev/touchscreen}
TSLIB_CONFFILE=/etc/ts.conf
export TSLIB_TSDEVICE
export TSLIB_CONFFILE
export TSLIB_PLUGINDIR=/usr/lib/ts
export TSLIB_CALIBFILE=/etc/pointercal
export QWS_DISPLAY=:1
export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH
export PATH=/bin:/sbin:/usr/bin/:/usr/sbin:/usr/local/bin
if [ -c /dev/touchscreen ]then
export
QWS_MOUSE_PROTO="Tslib:${TSLIB_TSDEVICE}
MouseMan:/dev/input/mice"
if [
-e
/etc/pointercal -a !
-s
/etc/pointercal ] then
rm
/etc/pointercal
fi
else
export
QWS_MOUSE_PROTO="MouseMan:/dev/input/mice"
>/etc/pointercal
fi
export QWS_KEYBOARD=TTY:/dev/tty1
export HOME=/root
cd /opt
./hello_qt4
-qws
1>/dev/null
2>/dev/null
hotplug
然后,重启开发板,hello_qt4程序运行了,再点button,播放器也d出来了。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)