基于图形视图框架遇到的一些列问题

时间:2023-02-01 18:43:17
我写的一个小程序,仿照Qt的例子里面的padnavigator这样一个旋转面板的效果
基于图形视图框架遇到的一些列问题
现在又两个问题,(1)在场景中我还嵌入式了一个自制的标题栏的窗口,使用QGraphicsProxyWidget类嵌入这个窗体,可是原本根据鼠标点击事件点击标题栏可以移动窗口却不行了,程序就死掉了,我调试了下是一个什么信号错误,原本在 QWidget体系里面是可用的,是因为在场景视图中信号传递不一样出问题了吗?有经验的能详解下吗?
(2)就是在图形视图框架中的使用布局管理器的,我因为就2个大窗体,我就用设置固定位置来布局,中间我也尝试了下QGraphicsView中的布局管理器,不过它好像都是针对QGraphicsWidget,QGraphicsItem或者是自己继承改造的类用了提示错误,我看了帮助文档是用这个QGraphicsLayoutItem去自己弄可以被布局管理器管理的对象吗? 请问这种混合的,如果窗体比较多要怎么使用布局管理,有详细介绍的例子吗?

15 个解决方案

#1


这个需要详细贴出你的出错代码,才好帮你解决,楼主最好单步跟一下,应该很容易的。

#2


引用 1 楼 LazyDreamHunter 的回复:
这个需要详细贴出你的出错代码,才好帮你解决,楼主最好单步跟一下,应该很容易的。
触发鼠标事件后提示是 底层由于接收到操作系统的信号而终止
         信号名称:SIGSEGV
         信号意义 : Segmentation fault  

#3


这种情况往往是由于底层发送的信号的目标不存在,比如,发送一个信号到一个不存在的对象上,就会包这个错误

#4


引用 2 楼 u011216653 的回复:
Quote: 引用 1 楼 LazyDreamHunter 的回复:

这个需要详细贴出你的出错代码,才好帮你解决,楼主最好单步跟一下,应该很容易的。
触发鼠标事件后提示是 底层由于接收到操作系统的信号而终止
         信号名称:SIGSEGV
         信号意义 : Segmentation fault  

这种段错误,好像经常是因为用new创建的对象,被delete了,还去操作;

#5


嗯,wenwu1225,说的不错,u011216653多从这方面找找,进入调式模式,看看调用栈,很快就能发现问题出在哪里

#6


引用 3 楼 LazyDreamHunter 的回复:
这种情况往往是由于底层发送的信号的目标不存在,比如,发送一个信号到一个不存在的对象上,就会包这个错误
找到错误了,是在重载鼠标移动的时候,还是用通过对父窗体的设定位置的方法来移动死掉了,现在这个Widget是用QGraphicsProxyWidget代理是处在图形视图框架中,那也是确定view然后设定位置吗?那么场景位置需要处理吗?这个要怎么实现单击标题栏实现移动呢?

#7


不太明白你的意思

#8


引用 7 楼 LazyDreamHunter 的回复:
不太明白你的意思

  
        QWidget *widget=this->parentWidget();
        QPoint point=widget->pos();
        point.setX(point.x()+e->x()-record.x());
        point.setY(point.y()+e->y()-record.y());
        widget->move(point);

我实现窗体移动的代码,调试在这出问题了,原来写的时候是放在QWidget体系中,QWidget *widget=this->parentWidget();获得主窗体是没错的,我想现在可能是因为我用QGraphicsProxyWidget代理放在视图框架中在使用parentWidget是不行的,所以我该如何实现随鼠标移动而移动呢?

#9


鼠标移动,应该放到mouseMoveEvent中实现,

#10


你要移动的是主窗口吗?如果是,这么操作:

1,如果你的主窗口是QGraphicsView对象,那么通过QGraphicsProxyWidget代理对象可以获得QGraphicsView对象,应该用这个QGraphicsView对象的move函数实现整个窗体的移动。

2,如果你的QGraphicsView对象是放在另外一个widget或者什么窗口上,那么你应该获得主窗口对象的指针,然后调用主窗口对象的move函数。

另外关于你的代码“QWidget *widget=this->parentWidget();”,由于QGraphicsProxyWidget代理对象不会自动有parentWidget,除非你指定,那么该函数会返回空指针0,调用0只想的move函数程序肯定会挂掉。而且这个parentWidget函数返回的widget,根本就不是QWidget指针,而是QGraphicsWidget指针,他们两者之间是有本质区别的。

#11


引用 10 楼 rjsloth 的回复:
你要移动的是主窗口吗?如果是,这么操作:

1,如果你的主窗口是QGraphicsView对象,那么通过QGraphicsProxyWidget代理对象可以获得QGraphicsView对象,应该用这个QGraphicsView对象的move函数实现整个窗体的移动。

2,如果你的QGraphicsView对象是放在另外一个widget或者什么窗口上,那么你应该获得主窗口对象的指针,然后调用主窗口对象的move函数。

另外关于你的代码“QWidget *widget=this->parentWidget();”,由于QGraphicsProxyWidget代理对象不会自动有parentWidget,除非你指定,那么该函数会返回空指针0,调用0只想的move函数程序肯定会挂掉。而且这个parentWidget函数返回的widget,根本就不是QWidget指针,而是QGraphicsWidget指针,他们两者之间是有本质区别的。

就是第一种情况,现在我该用什么办法获取QGraphicsView对象呢?

#12


引用 11 楼 u011216653 的回复:
Quote: 引用 10 楼 rjsloth 的回复:

你要移动的是主窗口吗?如果是,这么操作:

1,如果你的主窗口是QGraphicsView对象,那么通过QGraphicsProxyWidget代理对象可以获得QGraphicsView对象,应该用这个QGraphicsView对象的move函数实现整个窗体的移动。

2,如果你的QGraphicsView对象是放在另外一个widget或者什么窗口上,那么你应该获得主窗口对象的指针,然后调用主窗口对象的move函数。

另外关于你的代码“QWidget *widget=this->parentWidget();”,由于QGraphicsProxyWidget代理对象不会自动有parentWidget,除非你指定,那么该函数会返回空指针0,调用0只想的move函数程序肯定会挂掉。而且这个parentWidget函数返回的widget,根本就不是QWidget指针,而是QGraphicsWidget指针,他们两者之间是有本质区别的。

就是第一种情况,现在我该用什么办法获取QGraphicsView对象呢?


移动view的代码应该是在处理QGraphicsProxyWidget代理对象的鼠标移动事件函数中,应该是:
(this->scene()->views())[0]->move(x, y);
其中scene函数返回QGraphicsProxyWidget代理对象所在的场景,views函数返回所有正在显示该场景的view的指针序列(因为同一个scene可以同时被多个view显示),我想你应该只在一个view中显示你的scene,所以[0]表示取指向第一个显示scene的view的指针,最后move函数表示移动这个view,其中的x,y就是你想要它移动到的位置。语法上可能要再加括号,我没有实际试,你试试看。方法应该是这样的。

#13


借用一下你的代码就是:

QWidget *widget = (QWidget*)(this->scene()->views())[0]);
QPoint point=widget->pos();
point.setX(point.x()+e->x()-record.x());
point.setY(point.y()+e->y()-record.y());
widget->move(point);

#14


引用 13 楼 rjsloth 的回复:
借用一下你的代码就是:

QWidget *widget = (QWidget*)(this->scene()->views())[0]);
QPoint point=widget->pos();
point.setX(point.x()+e->x()-record.x());
point.setY(point.y()+e->y()-record.y());
widget->move(point);

谢谢,传了那个QGraphicsProxyWidget指针进来,才能调用scene函数就OK了。

#15


引用 14 楼 u011216653 的回复:
Quote: 引用 13 楼 rjsloth 的回复:

借用一下你的代码就是:

QWidget *widget = (QWidget*)(this->scene()->views())[0]);
QPoint point=widget->pos();
point.setX(point.x()+e->x()-record.x());
point.setY(point.y()+e->y()-record.y());
widget->move(point);

谢谢,传了那个QGraphicsProxyWidget指针进来,才能调用scene函数就OK了。


关于这个,我没有试过,但是如果我去做的话,我应该会继承QGraphicsProxyWidget类并重写mouseMoveEvent函数,然后用我自己的写的类去用函数setWidget(指定的widget指针),这样就不用“传那个QGraphicsProxyWidget指针进来”。这更符合面向对象的思想。

#1


这个需要详细贴出你的出错代码,才好帮你解决,楼主最好单步跟一下,应该很容易的。

#2


引用 1 楼 LazyDreamHunter 的回复:
这个需要详细贴出你的出错代码,才好帮你解决,楼主最好单步跟一下,应该很容易的。
触发鼠标事件后提示是 底层由于接收到操作系统的信号而终止
         信号名称:SIGSEGV
         信号意义 : Segmentation fault  

#3


这种情况往往是由于底层发送的信号的目标不存在,比如,发送一个信号到一个不存在的对象上,就会包这个错误

#4


引用 2 楼 u011216653 的回复:
Quote: 引用 1 楼 LazyDreamHunter 的回复:

这个需要详细贴出你的出错代码,才好帮你解决,楼主最好单步跟一下,应该很容易的。
触发鼠标事件后提示是 底层由于接收到操作系统的信号而终止
         信号名称:SIGSEGV
         信号意义 : Segmentation fault  

这种段错误,好像经常是因为用new创建的对象,被delete了,还去操作;

#5


嗯,wenwu1225,说的不错,u011216653多从这方面找找,进入调式模式,看看调用栈,很快就能发现问题出在哪里

#6


引用 3 楼 LazyDreamHunter 的回复:
这种情况往往是由于底层发送的信号的目标不存在,比如,发送一个信号到一个不存在的对象上,就会包这个错误
找到错误了,是在重载鼠标移动的时候,还是用通过对父窗体的设定位置的方法来移动死掉了,现在这个Widget是用QGraphicsProxyWidget代理是处在图形视图框架中,那也是确定view然后设定位置吗?那么场景位置需要处理吗?这个要怎么实现单击标题栏实现移动呢?

#7


不太明白你的意思

#8


引用 7 楼 LazyDreamHunter 的回复:
不太明白你的意思

  
        QWidget *widget=this->parentWidget();
        QPoint point=widget->pos();
        point.setX(point.x()+e->x()-record.x());
        point.setY(point.y()+e->y()-record.y());
        widget->move(point);

我实现窗体移动的代码,调试在这出问题了,原来写的时候是放在QWidget体系中,QWidget *widget=this->parentWidget();获得主窗体是没错的,我想现在可能是因为我用QGraphicsProxyWidget代理放在视图框架中在使用parentWidget是不行的,所以我该如何实现随鼠标移动而移动呢?

#9


鼠标移动,应该放到mouseMoveEvent中实现,

#10


你要移动的是主窗口吗?如果是,这么操作:

1,如果你的主窗口是QGraphicsView对象,那么通过QGraphicsProxyWidget代理对象可以获得QGraphicsView对象,应该用这个QGraphicsView对象的move函数实现整个窗体的移动。

2,如果你的QGraphicsView对象是放在另外一个widget或者什么窗口上,那么你应该获得主窗口对象的指针,然后调用主窗口对象的move函数。

另外关于你的代码“QWidget *widget=this->parentWidget();”,由于QGraphicsProxyWidget代理对象不会自动有parentWidget,除非你指定,那么该函数会返回空指针0,调用0只想的move函数程序肯定会挂掉。而且这个parentWidget函数返回的widget,根本就不是QWidget指针,而是QGraphicsWidget指针,他们两者之间是有本质区别的。

#11


引用 10 楼 rjsloth 的回复:
你要移动的是主窗口吗?如果是,这么操作:

1,如果你的主窗口是QGraphicsView对象,那么通过QGraphicsProxyWidget代理对象可以获得QGraphicsView对象,应该用这个QGraphicsView对象的move函数实现整个窗体的移动。

2,如果你的QGraphicsView对象是放在另外一个widget或者什么窗口上,那么你应该获得主窗口对象的指针,然后调用主窗口对象的move函数。

另外关于你的代码“QWidget *widget=this->parentWidget();”,由于QGraphicsProxyWidget代理对象不会自动有parentWidget,除非你指定,那么该函数会返回空指针0,调用0只想的move函数程序肯定会挂掉。而且这个parentWidget函数返回的widget,根本就不是QWidget指针,而是QGraphicsWidget指针,他们两者之间是有本质区别的。

就是第一种情况,现在我该用什么办法获取QGraphicsView对象呢?

#12


引用 11 楼 u011216653 的回复:
Quote: 引用 10 楼 rjsloth 的回复:

你要移动的是主窗口吗?如果是,这么操作:

1,如果你的主窗口是QGraphicsView对象,那么通过QGraphicsProxyWidget代理对象可以获得QGraphicsView对象,应该用这个QGraphicsView对象的move函数实现整个窗体的移动。

2,如果你的QGraphicsView对象是放在另外一个widget或者什么窗口上,那么你应该获得主窗口对象的指针,然后调用主窗口对象的move函数。

另外关于你的代码“QWidget *widget=this->parentWidget();”,由于QGraphicsProxyWidget代理对象不会自动有parentWidget,除非你指定,那么该函数会返回空指针0,调用0只想的move函数程序肯定会挂掉。而且这个parentWidget函数返回的widget,根本就不是QWidget指针,而是QGraphicsWidget指针,他们两者之间是有本质区别的。

就是第一种情况,现在我该用什么办法获取QGraphicsView对象呢?


移动view的代码应该是在处理QGraphicsProxyWidget代理对象的鼠标移动事件函数中,应该是:
(this->scene()->views())[0]->move(x, y);
其中scene函数返回QGraphicsProxyWidget代理对象所在的场景,views函数返回所有正在显示该场景的view的指针序列(因为同一个scene可以同时被多个view显示),我想你应该只在一个view中显示你的scene,所以[0]表示取指向第一个显示scene的view的指针,最后move函数表示移动这个view,其中的x,y就是你想要它移动到的位置。语法上可能要再加括号,我没有实际试,你试试看。方法应该是这样的。

#13


借用一下你的代码就是:

QWidget *widget = (QWidget*)(this->scene()->views())[0]);
QPoint point=widget->pos();
point.setX(point.x()+e->x()-record.x());
point.setY(point.y()+e->y()-record.y());
widget->move(point);

#14


引用 13 楼 rjsloth 的回复:
借用一下你的代码就是:

QWidget *widget = (QWidget*)(this->scene()->views())[0]);
QPoint point=widget->pos();
point.setX(point.x()+e->x()-record.x());
point.setY(point.y()+e->y()-record.y());
widget->move(point);

谢谢,传了那个QGraphicsProxyWidget指针进来,才能调用scene函数就OK了。

#15


引用 14 楼 u011216653 的回复:
Quote: 引用 13 楼 rjsloth 的回复:

借用一下你的代码就是:

QWidget *widget = (QWidget*)(this->scene()->views())[0]);
QPoint point=widget->pos();
point.setX(point.x()+e->x()-record.x());
point.setY(point.y()+e->y()-record.y());
widget->move(point);

谢谢,传了那个QGraphicsProxyWidget指针进来,才能调用scene函数就OK了。


关于这个,我没有试过,但是如果我去做的话,我应该会继承QGraphicsProxyWidget类并重写mouseMoveEvent函数,然后用我自己的写的类去用函数setWidget(指定的widget指针),这样就不用“传那个QGraphicsProxyWidget指针进来”。这更符合面向对象的思想。