Qt 程序右键单击时崩溃
我正在为一个大学项目开发视频编辑器。 guiVideoElement(黑色区域)是 guiVideoTrack(浅灰色区域)上视频素材的图形表示。使用 Shift+鼠标左键,您可以在 guiVideoElement 上进行选择(蓝色区域)。要使用选择,您可以通过右键单击所选区域来打开上下文菜单。
正如 本教程,我使用 contextMenuEvent 打开上下文菜单。不幸的是,整个程序崩溃并显示消息“程序意外完成。”,除非我还定义了 mousePressEvent。即使 mousePressEvent 方法为空,这也会有所帮助(见下文)。
这是我的选择代码:
#include "guiselection.h"
#include <QMouseEvent>
#include <QMenu>
#include <QDebug>
GuiSelection::GuiSelection(QWidget *parent, int pos) :
QLabel(parent)
{
this->setFixedSize(1,60);
this->setScaledContents(true);
this->setPixmap(QPixmap(":/track/gui_selection"));
this->move(pos, this->pos().y());
this->show();
}
void GuiSelection::contextMenuEvent(QContextMenuEvent *ev)
{
QMenu menu(this);
exampleAct = new QAction(tr("&cut"), this);
connect(exampleAct, SIGNAL(triggered()), this, SLOT(doSth()));
menu.addAction(exampleAct);
menu.exec(ev->globalPos());
}
void GuiSelection::doSth()
{
qDebug() << "do sth executed";
}
void GuiSelection::mousePressEvent(QMouseEvent *ev) { }
在 GuiSelection 类中引入鼠标按钮处理之前,在处理 guiVideoElement 本身上的 mousePressEvents 时,我有相同的行为。在 GuiSelection 中注释掉 contextMenuEvent 和 mousePressEvent 函数的同时执行下面的代码将会导致程序在打印“右键单击”和parentWidget->width()后崩溃。即程序在执行完 mousePressEvent 函数中的所有代码后崩溃。
#include "guivideoelement.h"
#include "tracks/videoelement.h"
#include "uitracks/guiselection.h"
#include "uitracks/guivideotrack.h"
#include <QPixmap>
#include <QMouseEvent>
#include <QKeyEvent>
#include <QApplication>
#include <QDebug>
GuiVideoElement::GuiVideoElement(GuiVideoTrack *parent, VideoElement *ve, int length) :
GuiTrackElement(parent)
{
...
}
void GuiVideoElement::mousePressEvent(QMouseEvent *ev)
{
if(guiSelection != NULL) {
delete guiSelection;
guiSelection = NULL;
}
if(ev->button() & Qt::LeftButton && QApplication::keyboardModifiers() & Qt::ShiftModifier)
{
guiSelection = new GuiSelection(this, ev->pos().x());
} else if(ev->button() & Qt::RightButton)
{
qDebug() << "right button clicked";
}
else {
lastX = this->pos().x();
lastStableX = this->pos().x();
// for exact distinction of position us global positions!
prevMousePos = mapFromGlobal(ev->globalPos()).x();
}
qDebug() << parentWidget->width();
}
void GuiVideoElement::mouseMoveEvent(QMouseEvent *ev)
{
...
}
...
知道我做错了什么吗?我运行的是 Ubuntu 11.04。其他运行 Windows 的团队成员告诉我,程序不会崩溃,当向左或向右单击时,选择就会消失。对我来说,当我左键单击所选内容时,什么也没有发生。
I'm working on a video editor for a university project. The guiVideoElement (black area) is the graphic representation of video material on a guiVideoTrack (light grey area). With Shift+left mouse button, you can make a selection (blue area) on the guiVideoElement. To work with the selection, you can open a context menu by right clicking on the selected area.
As suggested in this tutorial, I use the contextMenuEvent to open the context menu. Unfortunately, the whole program crashes with the message "The program has unexpectedly finished.", unless I also define the mousePressEvent. This helps even if the mousePressEvent method is empty (see below).
Here's my code for the selection:
#include "guiselection.h"
#include <QMouseEvent>
#include <QMenu>
#include <QDebug>
GuiSelection::GuiSelection(QWidget *parent, int pos) :
QLabel(parent)
{
this->setFixedSize(1,60);
this->setScaledContents(true);
this->setPixmap(QPixmap(":/track/gui_selection"));
this->move(pos, this->pos().y());
this->show();
}
void GuiSelection::contextMenuEvent(QContextMenuEvent *ev)
{
QMenu menu(this);
exampleAct = new QAction(tr("&cut"), this);
connect(exampleAct, SIGNAL(triggered()), this, SLOT(doSth()));
menu.addAction(exampleAct);
menu.exec(ev->globalPos());
}
void GuiSelection::doSth()
{
qDebug() << "do sth executed";
}
void GuiSelection::mousePressEvent(QMouseEvent *ev) { }
I had the same behaviour before introducing the mouse button handling in the GuiSelection class when handling mousePressEvents on the guiVideoElement itself. Executing the code below while commenting out the contextMenuEvent and mousePressEvent functions in the GuiSelection will make the program crash after printing "right button clicked" and parentWidget->width(). I.e. the program crashes after having executed all the code in the mousePressEvent function.
#include "guivideoelement.h"
#include "tracks/videoelement.h"
#include "uitracks/guiselection.h"
#include "uitracks/guivideotrack.h"
#include <QPixmap>
#include <QMouseEvent>
#include <QKeyEvent>
#include <QApplication>
#include <QDebug>
GuiVideoElement::GuiVideoElement(GuiVideoTrack *parent, VideoElement *ve, int length) :
GuiTrackElement(parent)
{
...
}
void GuiVideoElement::mousePressEvent(QMouseEvent *ev)
{
if(guiSelection != NULL) {
delete guiSelection;
guiSelection = NULL;
}
if(ev->button() & Qt::LeftButton && QApplication::keyboardModifiers() & Qt::ShiftModifier)
{
guiSelection = new GuiSelection(this, ev->pos().x());
} else if(ev->button() & Qt::RightButton)
{
qDebug() << "right button clicked";
}
else {
lastX = this->pos().x();
lastStableX = this->pos().x();
// for exact distinction of position us global positions!
prevMousePos = mapFromGlobal(ev->globalPos()).x();
}
qDebug() << parentWidget->width();
}
void GuiVideoElement::mouseMoveEvent(QMouseEvent *ev)
{
...
}
...
Any idea what I am doing wrong? I'm running Ubuntu 11.04. Other team members, who run Windows, tell me that the program does not crash for them, the selection simply disappears when clicking on it either left or right. For me, when I left click on the selection, nothing happens at all.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我的一个队友发现使用
而不是
解决问题。 Qt 文档也指出了这个方向(例如,请参见此处 和此处)。
A team mate of mine found that using
instead of
solves the problem. The Qt docs also point to that direction (e.g. see here and here).
在跟踪程序崩溃时,花时间学习如何使用调试器确实值得。这将允许您单步执行程序代码,并执行有用的操作,例如查看变量的值。如果程序崩溃,您将能够看到“调用堆栈”(即调用函数的顺序,以到达当前位置)。
When tracking down program crashes, it's really worth spending the time to learn how to use a debugger. This will allow you to step through the program's code, and do useful things like see the values of variables. And if the program crashes, you'll be able to see the 'call-stack' (that is, the order in which functions were called, to get to the current location).