- 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/
我有一个无 GUI 的服务器(没有任何桌面环境或 Ubuntu 服务器的新鲜 Debian,没有 X 服务器,先验)。 我考虑安装 docker 并拉取一个基于官方 Ubuntu 的容器,并在其上添加
我正在构建一个带有临时用户名系统的简单聊天服务器。当屏幕弹出时,首先会出现一个简单的屏幕,询问您的用户名。你可以放入任何你想要的东西,这纯粹是暂时的(我也在尝试)。代码告诉程序继续,将用户名保存到代码
我想将来自其他类的图像显示到 QLabel 中,但要通知 GUI 有一个新的框架可用。我需要从非 GUI 类和非 GUI 线程发出信号。 有什么办法吗? 最佳答案 signal 可以从任何继承QObj
我正在用 Java 编写一个图形用户界面,它有一些按钮,其中一个按钮是选项。我想要它,所以当您单击选项时,它会将 gui 更改为我的选项 gui,而不是在另一个窗口中打开它。 我该怎么做? 最佳答案
标题说明了一切...我和我的 friend 正在这样做,我们不知道为什么 Ball.java 实际上没有在 gamePanel 中制作球,然后制作 GUI。顺便说一句,这是 8 球台球。这是代码: 驱
我正在使用 GUI 构建器,我想知道是否有一种简单的方法可以通过当前主窗口打开寄存器窗口(引用下面的页面)。我正在尝试通过菜单栏来执行此操作。 我一整天都在尝试,因为 GUI Builder 生成了一
我有一个程序使用了许多隐藏的 GUI 组件。例如,所有菜单项和打印机对话框/组件(仅占用至少 50 毫秒)。总的来说,我猜整个程序启动的大约 300 毫秒(或 40%)要归功于所有隐藏的东西。 我想做
我对 GUI 构建比较陌生。 我想制作一个带有按钮(我已经有了)的 GUI,用户可以按下该按钮并选择一个图像,然后动态地将该图像加载到面板中的 GUI 中。我希望每次用户浏览图像时图像都动态变化。 到
我有两年使用 Java 和 Visual Studio 进行企业应用程序编程的经验,而且我是 Python 和 wxPython 的新手。所以我的问题是:wxPython 能否为我提供足够丰富的 GU
这是我启动 mkvtoolnix-gui 时遇到的错误: mkvtoolnix-gui: symbol lookup error: mkvtoolnix-gui: undefined symbol:
我在初始屏幕上有一些最近使用的存储库,我想删除它们,因为我不再使用它们了。如何删除它们? 操作系统 = Windows 7 我查看了注册表并搜索了 git 目录,但找不到最近使用列表的存储位置。 最佳
我正在尝试在 matlab、GUI 中用户输入点作为输入和它们之间的连接。 我有 5 个 matlab 文件 - screen1.m、screen2.m、screen3.m、screen4.m、glo
我用java制作了一个客户端/服务器程序,我已经按照我想要的方式使用cmd完美地工作了,现在我正在尝试将代码的客户端转换为GUI,但是我在打印时遇到问题客户端消息并从文本字段和服务器消息读取客户端输入
我正在制作一种 CRUD 应用程序(Java GUI,MYSQL)我应该: 将数据从数据库加载到List(例如),然后将List加载到GUI 将数据从数据库加载到对象(具有 SQL 表等属性)和对象到
我正在开发一个有 5 个图形用户界面窗口的 Java 应用程序,其中一个是问候窗口或主窗口,我已经完成了所有逻辑部分的工作,我已经完成了 99.99%,唯一剩下的就是我如何以这种方式编码,当我点击一个
我目前正在开发 GUI。 我选择将我的 GUI 基于 bluej 项目 - Scribble。 当您创建 ScribbleGUI 对象时,DrawDemo 类会创建一个同时自动打开的 Canvas 。
在这里阅读了很多关于多进程、管道等的内容后,我还没有找到答案,但如果它已经存在,我深表歉意。 我有一个外围硬件,我正在尝试为其创建一个 GUI。我想让 GUI 使用来自外围设备的数据不断更新,同时仍保
我想做的是将 GUI 从一个单独文件中的类链接到另一个类。我的第一个类是一个主菜单,它将显示一些链接到另一个窗口的按钮。第二个类显示不同的窗口,但我现在遇到的问题是我不知道如何链接第一个类中的按钮来调
我的 GUI 代码中有一个奇怪的行为。如果用户在短时间内产生大量事件,则可能会发生正在运行的事件处理程序方法被另一个事件处理程序方法中断。由于一切都在同一个线程(GUI 线程)中运行,所以一切都应该按
这是一个涉及风格的问题。我正在寻找可以帮助我解决常见 GUI 设计问题 的想法。该应用程序是在 Winforms 中完成的,宁愿使用 WPF,该应用程序已经完成,但我是一个完美主义者,在与其他人合作时
我是一名优秀的程序员,十分优秀!