我遇到了一些直接脱离Qt帮助的QRubberBand
代码崩溃。崩溃发生在setGeometry
电话。由于我能够使用qDebug访问几何体,因此创建了QRubberBand
实例,所以我很困惑。
上下文:代码在一个自定义的Widget中,它是这样创建的:
ImageLabel2* image = new ImageLabel2(this);
image->setPixmap(pix);
setCentralWidget(image);
我知道该实例仍然存在,因为注释掉setGeometry
调用以避免崩溃,继续输出调试语句。
我做错了什么?
调试输出:
mousePress QPoint(294,343)
该计划意外地完成了。
来自崩溃日志:
异常类型:EXC_BAD_ACCESS(SIGSEGV)异常代码: 0x000000000000000d,0x0000000000000000
代码:
void ImageLabel2::mousePressEvent(QMouseEvent *event)
{
qDebug() << "mousePress" << event->pos();
origin = event->pos();
if (!rubberBand){
rubberBand = new QRubberBand(QRubberBand::Rectangle, this);
}
qDebug() << rubberBand->geometry();
rubberBand->setGeometry(QRect(origin, QSize())); // CRASH
rubberBand->show();
}
答案 0 :(得分:2)
UPD:根据新信息,问题在于初始化。
通过支票
if (!rubberBand){
rubberBand = // initialize it
}
您希望rubberBand
指针最初等于零(NULL),并检查它。但除非你初始化这个指针,否则它既不会是0也不会是正确的地址。与任何其他未初始化的变量一样,它将包含 garbage ,即瞬间发生在内存中的一些随机值。使用这样的指针可以保证崩溃。
所以,对未初始化的变量说不!如果您希望它最初为NULL,使其为NULL。
因此,在您的自定义窗口小部件构造函数中将其初始化为
ImageLabel2::ImageLabel2() : rubberBand(NULL) {
// your constructor code
}
或
ImageLabel2::ImageLabel2() {
rubberBand = NULL;
// your constructor code
}
(没有区别)。如果您愿意,可以写0
而不是NULL
,但NULL
更常见。
之后,mousePressEvent
方法不需要修改。
旧答案(错误):
来自QSize default constructor的文档:
QSize :: QSize()
构造一个宽度和高度无效的大小 (即isValid()返回false)。
因此,您创建了一个无效的 QSize并将其传递给QRect。之后的崩溃可能是QRect或QRubberBand代码中的某种错误,或者未定义的行为。如果你想要0到0的大小,那么你应该使用QSize(0,0)
。这样的大小有效:
bool QSize :: isValid()const
如果width和height都等于或大于0,则返回true;否则返回false。
答案 1 :(得分:0)
您的错误可能来自您传递QSize()
作为参数的事实。
作为文档状态,QSize的默认构造函数创建一个无效对象