- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我的应用程序有一个 QMdiArea,在其中显示子窗口,其中包含 QGraphicsView 派生 View (GfxInteractiveView) 的实例,这反过来可视化包含自定义 QGraphicsItem 派生项目的场景。
/// An image item which is displayed as the background of a scene.
class GfxImageItem : public QObject, public QGraphicsPixmapItem
{
Q_OBJECT
protected:
GfxInteractiveImgView *view_;
QPixmap pixmap_;
QList<GfxPointItem *> pointItems_;
public:
GfxImageItem(GfxInteractiveImgView *view);
// set the pixmap to the image loaded from this path
bool load(const QString &path);
// normally not overriden, here just for tracing
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
QLOG("Painting image"); // homebrew macro for tracing
QGraphicsPixmapItem::paint(painter, option, widget);
}
};
/// A generated image drawn at the foreground of a scene.
class GfxMapItem : public QGraphicsPixmapItem
{
public:
GfxMapItem(QGraphicsItem *item);
void regenerateMap();
// same as GfxMapItem, here just for tracing
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
};
到目前为止一切顺利,但我还有另一个项目 GfxPointItem,它是完全自定义的,具有实际执行某些操作的 paint(),当我将其添加到场景中时,其中一个内核的 CPU 使用率跳升至满所有层次结构中的项目进入重绘循环,只要窗口可见或场景中存在自定义项目,该循环就会继续。发生这种情况时看一下堆栈表明我的函数都不负责调用 paint(),事件是在事件循环中生成的。这是 GfxPointItem 的代码:
/// A draggable item representing an analysis point on the map, drawn on top of the map.
class GfxPointItem : public QGraphicsObject
{
Q_OBJECT
protected:
GfxImageItem *imgParent_;
GfxInteractiveImgView *view_;
int size_, fontSize_;
QColor color_, oldColor_;
qreal paintScale_;
QRectF boundingRect_;
bool active_, static_;
QStaticText pointText_, valueText_;
public:
GfxPointItem(GfxImageItem *parent, GfxInteractiveImgView *view, const QPointF &pos);
void setActive(bool arg);
void setStatic(bool arg);
void setColor(const QColor &color) { color_ = color; update(); }
virtual QRectF boundingRect() const { return boundingRect_; }
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
signals:
void changedPos(int index, QPointF newpos);
public slots:
void setPaintScale(qreal value);
void setPointText(const QString &text);
void setValueText(const QString &text);
protected:
void updateBoundRect();
void updatePointText();
QPoint valueTextPos() const;
QPoint pointTextPos() const;
};
GfxPointItem::GfxPointItem(GfxImageItem *parent, GfxInteractiveImgView *view, const QPointF &pos, int index) : QGraphicsObject(parent),
imgParent_(parent),
view_(view),
index_(index), size_(8), fontSize_(8),
color_(Qt::black),
paintScale_(view->invscale()),
drawLabel_(true), active_(false), static_(false), floatPrec_(false)
{
QLOGX("Creating new at " << pos.x() << "," << pos.y() << ", index: " << index);
setPos(pos);
updatePointText();
connect(view, SIGNAL(scaleChanged(qreal)), this, SLOT(setPaintScale(qreal)));
}
/// An inactive point wil not respond to hover events and will not be movable.
void GfxPointItem::setActive(bool arg)
{
QLOGX("Setting active state: " << arg);
active_ = arg;
setAcceptHoverEvents(arg);
setFlag(QGraphicsItem::ItemIsMovable, arg);
}
/// Set or disable static mode on point. In static mode, the point text is not updated when changing position, so it can retain a constant label.
void GfxPointItem::setStatic(bool arg)
{
QLOGX("Setting static mode: " << arg);
static_ = arg;
}
void GfxPointItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
QLOGX("Painting point");
static const int margin = 2;
setScale(paintScale_);
QPen pen;
pen.setWidth(1);
pen.setColor(color_);
painter->setPen(pen);
// paint the centerpoint marker (two crossed lines)
painter->drawLine(QPointF(-size_, 0), QPointF( size_, 0));
painter->drawLine(QPointF(0, -size_), QPointF(0, size_));
// the label box and the two static text lines inside
pen.setWidth(0);
painter->setPen(pen);
QFont font;
font.setPointSize(fontSize_);
painter->setFont(font);
QBrush brush(Qt::SolidPattern);
brush.setColor(QColor(255, 255, 127)); // sand yellow
painter->setBrush(brush);
// point text size, value text size
QSizeF pts = pointText_.size(),
vts = valueText_.size();
// point text position, value text position
QPoint vtp = valueTextPos(),
ptp = pointTextPos();
// point id and position label and value indicator label in a rectangular box
int shift = (valueText_.text().isEmpty()) ? 0 : vts.height();
QRectF rect(ptp.x()-margin, ptp.y(), std::max(pts.width(), vts.width())+margin, pts.height() + shift);
painter->drawRect(rect);
painter->drawStaticText(ptp, pointText_);
painter->drawStaticText(vtp, valueText_);
}
void GfxPointItem::setPaintScale(qreal value)
{
QLOGX("Updating scale: " << value);
paintScale_ = value;
update();
}
void GfxPointItem::setPointText(const QString &text)
{
QLOGX("Setting text: " << text);
pointText_.setText(text);
updateBoundRect();
update();
}
void GfxPointItem::setValueText(const QString &text)
{
QLOGX("Setting value text: " << text);
valueText_.setText(text);
updateBoundRect();
update();
}
void GfxPointItem::updateBoundRect()
{
QLOGX("Updating bounding rect");
boundingRect_.setRect(- size_, pointTextPos().y(),
(2 * size_) + std::max(pointText_.size().width(), valueText_.size().width()),
(2 * size_) + pointText_.size().height() + valueText_.size().height());
}
void GfxPointItem::updatePointText()
{
QLOGX("Updating point text");
pointText_.setText("P" + QString::number(index_ + 1) + " ("
+ (floatPrec_ ? QString::number(pos().x()) : QString::number(std::floor(pos().x()))) + ","
+ (floatPrec_ ? QString::number(pos().y()) : QString::number(std::floor(pos().y()))) + ")");
updateBoundRect();
update();
}
void GfxPointItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
QLOGX("Mouse move");
QPointF p = pos();
QPointF ep = event->pos();
QGraphicsItem::mouseMoveEvent(event);
if (!static_) updatePointText();
emit changedPos(index_, pos());
}
我不知道为什么事件循环不断地重新绘制项目。我什至没有注意到这一点,但我在显示标准 QFileDialog::getExistingDirectory() 时遇到了问题,当带有图形项目的窗口可见时,它甚至无法绘制,因为重新绘制偷走了所有执行时间主线程远离它,导致卡住。之后,我向绘制函数添加了跟踪语句,并在几秒钟后在日志文件中发现了数万个条目,而应用程序似乎什么也没做。在任务管理器中,当窗口可见时(在 4 核处理器上)CPU 使用率约为 25%,当我关闭它时它下降到 0。
我的代码都没有强制这些重绘,那是什么?我如何调试事件循环以找到此行为的根源,这会减慢我的应用程序并导致卡住?
谢谢!
Qt 版本是最新的 5.0.2 二进制包,应用程序是使用 Visual C++ 2012 for x64 编译的。
最佳答案
在我看来,当在 paint
中调用 setScale
时,它连接到 setPaintScale
,然后调用 QWidget 的 update
函数,然后使该区域无效,当它返回到主事件循环时会导致 repaint .
因此,每次调用 paint 方法时,您最终都会获得 1 个 paint required 事件。
关于c++ - 为什么我的自定义图形项在基于 Qt 的 C++ GUI 应用程序中不断重新绘制?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17324152/
我有一个包含数字和整数的文件,我只想读取整数, 如果它们令人讨厌,请忽略宏,但是我只需要有整数,但是我必须确保还要读取字符串,然后忽略它们 我必须在这里修改什么: #include #include
我有一个这样格式化的txt文件: MyDepartureTown MyDestinationTown 123.45 Vehicle 12 我正在尝试将数据导入到我的 C 程序中。这是我用来实现这一目标
我创建了一个简单的文件,使用 flex,它生成了一个文件 lex.yy.c,现在,我想把它放到 C++ 程序中。 %{ #include %} %% stop printf("Stop co
我的一个程序用 c++ 代码生成一个大文件。有没有办法从另一个C++类调用将生成的代码插入其中? 这是一个小例子,可以清楚地说明我想要实现的目标。 生成的文件示例: FirstClass first
我需要了解我的程序“检查输入十六进制消息的第三个位置” 程序将采用十六进制值输入消息。例如0x0123456789abcdef 程序将检查输入消息的第三个位置,即 0 现在程序将采用另一条十六进制值的
当我将输入从输入文件重定向到 yacc 程序时,在它完成解析文件后,我希望 yacc 解析器打印其所做操作的摘要。如果我通过键盘输入内容然后按 Ctrl+D,我希望它执行相同的操作。有办法做到这一点吗
我正在扫描该文件,但它有两种不同的结构。 文件: ParisRoubaix "Marco MARCATO" 33 UAD ITA 26 5:43:31 ParisRoubaix "Sam BEWLEY
我想将winsock2.lib 添加到我的程序中,但不希望将其包含到最终的可执行文件中。有什么方法可以让我动态加载与winsock2关联的dll吗?如果没有,是否有任何 dll(Windows 附带)
我尝试了一个基本程序来将数据从数据库表检索到java程序中。编译结束后,运行代码时出现异常。控制台中没有显示错误。显示异常消息 import java.sql.*; public class clas
我想用 C++ 创建一个跨平台安装程序。它可以是任何压缩类型,例如 zip 或 gzip,像普通安装程序一样嵌入程序本身。我不想在不同的平台、linux 和 windows 上创建很多更改。如何跨平台
每次尝试用鼠标输入两个顶点时,我都会崩溃。我最近改变了组织每个形状的方式,以确保新形状与旧形状重叠。 这个项目的想法是制作各种交互式 Canvas 。用户可以在直线、三角形和矩形之间进行选择,然后选择
我想在我的程序中显示以下文本。当我在 python 中粘贴以下文本时,它会将反斜杠解释为转义序列并弄乱我的 ascii 艺术..任何解决这个问题的想法极客。这是我的文本想出现在我的节目中 _ _
我正在尝试加载名为 Tut16_ReadText.txt 的文件,并使其运行程序以输出其重或轻。 我收到了粘贴在下面的错误。我无法抽出时间让这个程序运行。谁能解释一下我必须做什么才能使这个程序正常工作
我想使用命令行将列表作为参数传递,例如: $python example.py [1,2,3] [4,5,6] 我希望第一个列表 [1,2,3] 成为 first_list,[4,5,6] 成为 se
在分析 C# 应用程序时,我发现名为“ThePreStub”的系统 (?) 方法中有相当多的 CPU 使用率。这是什么? 最佳答案 参见:CLR Inside out - The Performanc
关闭。这个问题需要更多focused .它目前不接受答案。 想改进这个问题吗? 更新问题,使其只关注一个问题 editing this post . 关闭 9 年前。 Improve this qu
我正在用 Python 开发一个游戏,想知道如何给它自己的图标。我使用的是 Windows 计算机,没有安装 Python 的额外东西。哦,我也在使用 3.3 版,这甚至可能吗? P.S 我在 Sta
我正在使用 tkinter 使用 Python 开发一个项目,该项目将允许对 IP 地址进行地理定位。我有原始转换,我可以获取 IP 地址并知道城市、州、国家、经度、纬度等。我想知道是否有任何方法可以
我编写了一个程序,您可以在其中选择任意数字并将其与任意数字的幂相关联。代码运行正常,直到它到达某个部分,然后我必须输入一个字符以使其移动到代码的下一部分。这就是我的意思: #include int
我正在编写“HACKING Art Of Exploitation”一书练习 Convert2.c 第 61 页。 这是我的代码。下面是我的问题。 #include void usage(char
我是一名优秀的程序员,十分优秀!