在Qt5中绘制大量独立角色的最佳方法?

2023-12-01

我正在编写一个显示大量文本的应用程序。但它不是单词和句子,而是以 CP437 字符集显示的二进制数据。目前的形式:

Screenshot of my current application

但我在绘制这些角色时遇到了问题。我需要一一绘制每个角色,因为稍后我想应用不同的颜色。这些字符也应该有透明的背景,因为稍后我想在背景中绘制具有不同颜色的部分和范围(根据某些标准对这些字符进行分组)。

该应用程序支持同时打开多个文件,但当打开多个文件时,绘图在快速 i7 上开始明显,因此可能写得不好。

在 Qt5 中绘制此类数据的最佳方法是什么?我应该将字符预渲染到位图并从那里开始,还是实际上可以通过使用普通的 Qt 函数来绘制文本来绘制大量字符?

Edit: 我用的是普通的QFrame进行绘图的小部件paintEvent, using QPainter。这是错误的做法吗?我读过一些文档QGraphicsScene,我记得它最适合在小部件需要对其绘制的对象进行一些控制的情况下使用。我不需要对我画的东西进行任何控制;我只需要画出来就可以了。我不会引用任何特定角色after我会画它。

该小部件有 2000 行,所以我不会粘贴整个代码,但目前我的绘制方法是这样的:

  • 首先,创建一个表(cache)有 256 个条目,将迭代器计数器设置为i多变的,
  • 对于每个条目,创建一个QStaticText对象包含有关由 ASCII 代码标识的字符的绘图信息(取自i多变的,
  • 稍后,在绘图函数中,对于输入流(即来自文件)中的每个字节,使用以下命令绘制数据QStaticText来自cache桌子。所以,绘制 ASCII 字符0x7A,我抬头看看QStaticText来自索引0x7a in cache表,然后喂这个QStaticText对象进入QPainter object.

我还尝试了一种不同的方法,将整条线渲染为一个QPainter::drawText调用,确实更快,但我失去了用不同颜色为每个角色着色的可能性。我希望有这样的可能性。


使用一个QGraphicsScene不会改善事情 - 它是一个额外的层QWidget。您追求的是原始性能,所以您不应该使用它。

你可以实施一个QTextDocument作为内存缓冲区/文件的可见部分的视图模型,但绘制新的QTextDocument每次滚动不会比直接在屏幕上绘制东西快QWidget.

Using QStaticText是朝着正确方向迈出的一步,但还不够:渲染QStaticText仍然需要字形形状的光栅化。您可以做得更好并缓存每个的像素图QChar, QColor您希望渲染的组合:这比光栅化字符轮廓要快得多,无论是否使用QStaticText or not.

然后,您可以从缓存中绘制像素图,而不是绘制单个字符。这次提交演示了这种方法。人物绘制方法为:

void drawChar(const QPointF & pos, QChar ch, QColor color, QPainter & p) {
    auto & glyph = m_cache[{ch, color}];
    if (glyph.isNull()) {
        glyph = QPixmap{m_glyphRect.size().toSize()};
        glyph.fill(Qt::white);
        QPainter p{&glyph};
        p.setPen(color);
        p.setFont(m_font);
        p.drawText(m_glyphPos, {ch});
    }
    p.drawPixmap(pos, glyph);
}

您还可以缓存每个(字符,前景,背景)元组。唉,当有很多前景/背景组合时,这种情况很快就会失控。

如果所有背景都是相同的颜色(例如白色),您希望存储角色的负掩码:glyph具有白色背景和透明形状。这次提交演示了这种方法。字形矩形填充字形颜色,然后在顶部应用白色蒙版:

void drawChar(const QPointF & pos, QChar ch, QColor color, QPainter & p) {
    auto & glyph = m_glyphs[ch];
    if (glyph.isNull()) {
        glyph = QImage{m_glyphRect.size().toSize(), QImage::Format_ARGB32_Premultiplied};
        glyph.fill(Qt::white);
        QPainter p{&glyph};
        p.setCompositionMode(QPainter::CompositionMode_DestinationOut);
        p.setFont(m_font);
        p.drawText(m_glyphPos, {ch});
    }
    auto rect = m_glyphRect;
    rect.moveTo(pos);
    p.fillRect(rect, color);
    p.drawImage(pos, glyph);
}

您可以只存储 alpha 遮罩并按需合成它们,而不是存储给定颜色的完全预渲染的字符:

  1. 从透明背景上预渲染的白色字形开始(CompositionMode_Source).
  2. 用背景填充字形矩形CompositionMode_SourceOut:背景将保留角色本身的孔。
  3. 用前景填充字形矩形CompositionMode_DestinationOver:前景将填补这个洞。
  4. (可选)如果您尚未在小部件上绘制,则在小部件上绘制合成。

事实证明,这相当快,并且渲染是完全可并行的 - 请参阅下面的示例。

注意:预渲染的字形可以使用颜色与 Alpha 的进一步预乘来显得不那么粗。

另一种具有出色性能的方法是使用 GPU 模拟文本模式显示。将预渲染的字形轮廓存储在纹理中,将要渲染的字形索引和颜色存储在数组中,并使用 OpenGL 和两个着色器进行渲染。这个例子可能是实施这种方法的起点。

下面是一个使用 CPU 跨多个线程渲染的完整示例。

screenshot of the example

我们从后备存储视图开始,用于生成QImage是给定小部件的后备存储的视图,可用于并行绘制。

在 2013 iMac 上,此代码在大约 8 毫秒内重新绘制全屏小部件。

// https://github.com/KubaO/stackoverflown/tree/master/questions/hex-widget-40458515
#include <QtConcurrent>
#include <QtWidgets>
#include <algorithm>
#include <array>
#include <cmath>

struct BackingStoreView {
    QImage *dst = {};
    uchar *data = {};
    const QWidget *widget = {};
    explicit BackingStoreView(const QWidget *widget) {
        if (!widget || !widget->window()) return;
        dst = dynamic_cast<QImage*>(widget->window()->backingStore()->paintDevice());
        if (!dst || dst->depth() % 8) return;
        auto byteDepth = dst->depth()/8;
        auto pos = widget->mapTo(widget->window(), {});
        data = const_cast<uchar*>(dst->constScanLine(pos.y()) + byteDepth * pos.x());
        this->widget = widget;
    }
    // A view onto the backing store of a given widget
    QImage getView() const {
        if (!data) return {};
        QImage ret(data, widget->width(), widget->height(), dst->bytesPerLine(), dst->format());
        ret.setDevicePixelRatio(widget->devicePixelRatio());
        return ret;
    }
    // Is a given image exactly this view?
    bool isAView(const QImage &img) const {
        return data && img.bits() == data && img.depth() == dst->depth()
                && img.width() == widget->width() && img.height() == widget->height()
                && img.bytesPerLine() == dst->bytesPerLine() && img.format() == dst->format();
    }
};

然后,CP437字符集:

static auto const CP437 = QStringLiteral(
            " ☺☻♥♦♣♠•◘○◙♂♀♪♫☼▶◀↕‼¶§▬↨↑↓→←∟↔▲▼"
            "␣!\"#$%&'()*+,-./0123456789:;<=>?"
            "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"
            "`abcdefghijklmnopqrstuvwxyz{|}~ "
            "ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒ"
            "áíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐"
            "└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀"
            "αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ ");

The HexView小部件源自QAbstractScrollArea并可视化内存映射的数据块:

class HexView : public QAbstractScrollArea {
    Q_OBJECT
    QImage const m_nullImage;
    const int m_addressChars = 8;
    const int m_dataMargin = 4;
    const char * m_data = {};
    size_t m_dataSize = 0;
    size_t m_dataStart = 0;
    QSize m_glyphSize;
    QPointF m_glyphPos;
    int m_charsPerLine, m_lines;
    QMap<QChar, QImage> m_glyphs;
    QFont m_font{"Monaco"};
    QFontMetricsF m_fm{m_font};
    struct DrawUnit { QPoint pos; const QImage *glyph; QColor fg, bg; };
    QFutureSynchronizer<void> m_sync;
    QVector<DrawUnit> m_chunks;
    QVector<QImage> m_stores;
    using chunk_it = QVector<DrawUnit>::const_iterator;
    using store_it = QVector<QImage>::const_iterator;

    static inline QChar decode(char ch) { return CP437[uchar(ch)]; }
    inline int xStep() const { return m_glyphSize.width(); }
    inline int yStep() const { return m_glyphSize.height(); }
    void initData() {
        int const width = viewport()->width() - m_addressChars*xStep() - m_dataMargin;
        m_charsPerLine = (width > 0) ? width/xStep() : 0;
        m_lines = viewport()->height()/yStep();
        if (m_charsPerLine && m_lines) {
            verticalScrollBar()->setRange(0, m_dataSize/m_charsPerLine);
            verticalScrollBar()->setValue(m_dataStart/m_charsPerLine);
        } else {
            verticalScrollBar()->setRange(0, 0);
        }
    }
    const QImage &glyph(QChar ch) {
        auto &glyph = m_glyphs[ch];
        if (glyph.isNull()) {
            QPointF extent = m_fm.boundingRect(ch).translated(m_glyphPos).bottomRight();
            glyph = QImage(m_glyphSize, QImage::Format_ARGB32_Premultiplied);
            glyph.fill(Qt::transparent);
            QPainter p{&glyph};
            p.setPen(Qt::white);
            p.setFont(m_font);
            p.translate(m_glyphPos);
            p.scale(std::min(1.0, (m_glyphSize.width()-1)/extent.x()),
                    std::min(1.0, (m_glyphSize.height()-1)/extent.y()));
            p.drawText(QPointF{}, {ch});
        }
        return glyph;
    }

并行渲染是在类方法中完成的 - 除了访问只读数据和渲染到后备存储之外,它们不会修改小部件的状态。每个线程都作用于存储中的隔离线。

    static void drawChar(const DrawUnit & u, QPainter &p) {
        const QRect rect(u.pos, u.glyph->size());
        p.setCompositionMode(QPainter::CompositionMode_Source);
        p.drawImage(u.pos, *u.glyph);
        p.setCompositionMode(QPainter::CompositionMode_SourceOut);
        p.fillRect(rect, u.bg);
        p.setCompositionMode(QPainter::CompositionMode_DestinationOver);
        p.fillRect(rect, u.fg);
    }
    static QFuture<void> submitChunks(chunk_it begin, chunk_it end, store_it store) {
        return QtConcurrent::run([begin, end, store]{
            QPainter p(const_cast<QImage*>(&*store));
            for (auto it = begin; it != end; it++)
                drawChar(*it, p);
        });
    }

此方法在线程之间分配工作块:

    int processChunks() {
        m_stores.resize(QThread::idealThreadCount());
        BackingStoreView view(viewport());
        if (!view.isAView(m_stores.last()))
            std::generate(m_stores.begin(), m_stores.end(), [&view]{ return view.getView(); });
        std::ptrdiff_t jobSize = std::max(128, (m_chunks.size() / m_stores.size())+1);
        auto const cend = m_chunks.cend();
        int refY = 0;
        auto store = m_stores.cbegin();
        for (auto it = m_chunks.cbegin(); it != cend;) {
            auto end = it + std::min(cend-it, jobSize);
            while (end != cend && (end->pos.y() == refY || (refY = end->pos.y(), false)))
                end++; // break chunks across line boundaries
            m_sync.addFuture(submitChunks(it, end, store));
            it = end;
            store++;
        }
        m_sync.waitForFinished();
        m_sync.clearFutures();
        m_chunks.clear();
        return store - m_stores.cbegin();
    }

其余的实现是没有争议的:

protected:
    void paintEvent(QPaintEvent *ev) override {
        QElapsedTimer time;
        time.start();
        QPainter p{viewport()};
        QPoint pos;
        QPoint const step{xStep(), 0};
        auto dividerX = m_addressChars*xStep() + m_dataMargin/2.;
        p.drawLine(dividerX, 0, dividerX, viewport()->height());
        int offset = 0;
        QRect rRect = ev->rect();
        p.end();
        while (offset < m_charsPerLine*m_lines && m_dataStart + offset < m_dataSize) {
            const auto address = QString::number(m_dataStart + offset, 16);
            pos += step * (m_addressChars - address.size());
            for (auto c : address) {
                if (QRect(pos, m_glyphSize).intersects(rRect))
                    m_chunks.push_back({pos, &glyph(c), Qt::black, Qt::white});
                pos += step;
            }
            pos += {m_dataMargin, 0};
            auto bytes = std::min(m_dataSize - offset, (size_t)m_charsPerLine);
            for (int n = bytes; n; n--) {
                if (QRect(pos, m_glyphSize).intersects(rRect))
                    m_chunks.push_back({pos, &glyph(decode(m_data[m_dataStart + offset])), Qt::red, Qt::white});
                pos += step;
                offset ++;
            }
            pos = {0, pos.y() + yStep()};
        }
        int jobs = processChunks();
        newStatus(QStringLiteral("%1ms n=%2").arg(time.nsecsElapsed()/1e6).arg(jobs));
    }
    void resizeEvent(QResizeEvent *) override {
        initData();
    }
    void scrollContentsBy(int, int dy) override {
        m_dataStart = verticalScrollBar()->value() * (size_t)m_charsPerLine;
        viewport()->scroll(0, dy * m_glyphSize.height(), viewport()->rect());
    }
public:
    HexView(QWidget * parent = nullptr) : HexView(nullptr, 0, parent) {}
    HexView(const char * data, size_t size, QWidget * parent = nullptr) :
        QAbstractScrollArea{parent}, m_data(data), m_dataSize(size)
    {
        QRectF glyphRectF{0., 0., 1., 1.};
        for (int i = 0x20; i < 0xE0; ++i)
            glyphRectF = glyphRectF.united(m_fm.boundingRect(CP437[i]));
        m_glyphPos = -glyphRectF.topLeft();
        m_glyphSize = QSize(std::ceil(glyphRectF.width()), std::ceil(glyphRectF.height()));
        initData();
    }
    void setData(const char * data, size_t size) {
        if (data == m_data && size == m_dataSize) return;
        m_data = data;
        m_dataSize = size;
        m_dataStart = 0;
        initData();
        viewport()->update();
    }
    Q_SIGNAL void newStatus(const QString &);
};

我们利用现代 64 位系统并对源文件进行内存映射,以便通过小部件进行可视化。出于测试目的,还提供了字符集视图:

int main(int argc, char ** argv) {
    QApplication app{argc, argv};
    QFile file{app.applicationFilePath()};
    if (!file.open(QIODevice::ReadOnly)) return 1;
    auto *const map = (const char*)file.map(0, file.size(), QFile::MapPrivateOption);
    if (!map) return 2;

    QWidget ui;
    QGridLayout layout{&ui};
    HexView view;
    QRadioButton exe{"Executable"};
    QRadioButton charset{"Character Set"};
    QLabel status;
    layout.addWidget(&view, 0, 0, 1, 4);
    layout.addWidget(&exe, 1, 0);
    layout.addWidget(&charset, 1, 1);
    layout.addWidget(&status, 1, 2, 1, 2);
    QObject::connect(&exe, &QPushButton::clicked, [&]{
        view.setData(map, (size_t)file.size());
    });
    QObject::connect(&charset, &QPushButton::clicked, [&]{
        static std::array<char, 256> data;
        std::iota(data.begin(), data.end(), char(0));
        view.setData(data.data(), data.size());
    });
    QObject::connect(&view, &HexView::newStatus, &status, &QLabel::setText);
    charset.click();
    ui.resize(1000, 800);
    ui.show();
    return app.exec();
}

#include "main.moc"
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在Qt5中绘制大量独立角色的最佳方法? 的相关文章

  • Qt-Qlist 检查包含自定义类

    有没有办法覆盖加载自定义类的 Qt QList 的比较机制 即在 java 中你只需要重写一个比较方法 我有一个带有我的自定义类模型的 QList QList
  • 在高 dpi Windows 平台上自动重新缩放应用程序?

    我正在编写一个需要在高 dpi Windows 192dpi 而不是 96dpi 上运行的 Qt 应用程序 不幸的是 Qt 框架尚不支持高 dpi 至少在 Windows 上 因此我的应用程序及其所有元素看起来只有应有尺寸的一半 有没有办法
  • Qt 5.3 无法使 QCompass (QSensor) 在 Windows 8.1 上工作

    我无法让传感器在我的 Asus Transformer T100 上工作 磁力计和指南针无法启动 并且我从加速度计获得假值 始终 x 0 y 9 8 z 0 即使使用我的笔记本电脑 我总是得到相同的结果 第一段文字编辑 Initialisa
  • Qt - 获取互联网上托管的网页的源代码(HTML 代码)

    我想获取网页的源代码 HTML 例如StackOverflow的主页 这是我到目前为止编写的代码 QNetworkAccessManager manager QNetworkReply response manager get QNetwo
  • 如何将 zlib 添加到现有的 qt 安装中

    如何将 zlib 添加到 Qt 的现有安装中 我对此很陌生 所以请给我详细的描述 提前感谢您的帮助 zlib 包含在 Qt 核心库中 如果你想在 Qt 程序中使用 zlib 函数 你只需要包含 src 3rdparty zlib 中的 zl
  • 使用 Spring 进行 Swing GUI 开发

    是否有任何使用 Spring 最好是 v3 构建 Swing GUI 应用程序的不错的教程 这是可能的 但如果您想使用 GUI 构建器 则无法通过 spring 初始化任何 GUI 组合 所以你不能使用依赖注入之类的东西 Spring 管理
  • 如何使用 JavaScript 选择预节点/块中的文本?

    我了解不允许 JS 将任意文本复制到剪贴板背后的安全原因 但是是否有一种方法可以通过单击按钮来选择预节点中的文本 类似于 select 函数在输入中的工作方式 我不是在寻找复制到剪贴板的 jQuery 插件 我只想突出显示预块中的文本 以便
  • 是否可以在 Qt Creator 中将 Qt 样式表与升级的小部件一起使用?

    我正在尝试使用 Qt 样式表对标准小部件进行一些重大的重新设计 因此 在为不同的小部件手动完成大部分工作之后 objectName选择器 我决定以某种方式对类似的小部件进行分组 例如我有多个QFrames其作用类似于内部表单中的标题 我希望
  • 如何访问Loader的sourceComponent中的QML对象?

    我可能需要读取或写入的一些属性Loader s sourceComponent来自一些外部函数 访问该房产的方式是什么x里面的对象的Loader s sourceComponent import QtQuick 2 0 Item width
  • 如何将 Jfreechart(饼图)添加到 netbeans 的面板中

    我正在使用 netbeans gui 编辑器 并且正在尝试添加一个本身位于内部框架中的 Jfreechart 并且这个内部框架我想将其添加到面板中 正如您在此图中看到的那样 抱歉 我无法直接发布图像 因为我新手 http www flick
  • Python Tkinter,显示实时数据

    我想在 GUI 中显示实时数据tkinter 我得到的数据包含list两个整数的 current voltage 我每秒都在获取新数据 我成功创建了一个 GUI 现在我想知道如何在 GUI 中显示数据Label小部件 python tkin
  • 使用 PyQt 和 matplotlib 在可滚动小部件中显示多个绘图

    由于我没有得到答案this https stackoverflow com questions 12179893 creating a scrollable multiplot with pythons pylab我尝试用 PyQt 解决这
  • 将 UTC 格式的 QDateTime 转换为本地系统时间

    我从这样的字符串构造 QDateTime QDateTime date QDateTime fromString 2010 10 25T10 28 58 570Z yyyy MM ddTHH mm ss zzzZ 我知道date是 UTC
  • QWidget::showMinimized() 不起作用

    在 Ubuntu 13 04 上 如果使用QWidget showMinimized 为了最小化窗口 我发现通过单击系统任务栏上的应用程序图标恢复它后 调用QWidget showMinimized 无法工作 connect minimum
  • 使用 Qt 的网络服务

    我正在寻找使用 Qt 服务器端 实现 Web 服务的代码 如果您有任何信息 我将不胜感激 Regards 您可以使用libqxt http libqxt bitbucket org doc 0 6 qxtweb html实现服务器端Web服
  • 常量类成员、赋值运算符和 QList

    请确认我是否正确并告诉我是否有更好的解决方案 我了解具有常量成员的对象 例如int const width 无法由编译器隐式创建的合成赋值运算符处理 但是 QList 我想 std list 也是如此 需要一个有效的赋值运算符 因此 当我想
  • 当从 html 文件读取 Unicode 内容时,为什么 Unicode 字体在 QTextBrowser 中无法正确显示?

    我正在读一本html文件 该文件基本上包含Unicode案文如下 b akko sati kru akkh ti khy abbahati b h b But the QText浏览器不解释Unicode字体 所以QText浏览器显示如下
  • 扩展 TabViewStyle styleData

    我目前正在尝试找到一种更好的方法来执行此操作 将图标添加到选项卡 现在 我正在放弃 styleData title 以包含图标源 但如果能够扩展 styleData 就更好了 这样我就可以包含其他自定义属性 这是我当前的黑客 Tab tit
  • Qt 图表和数据可视化小部件

    我已经安装了 Qt 5 7 来尝试 Qt 图表和 Qt 数据可视化 但我在 Qt Designer 和 Qt Creator 中都找不到新的小部件 有什么建议我应该做什么才能让新的小部件出现在设计器中 我今天遇到了完全相同的问题 默认情况下
  • 如何从 Qt 应用程序通过 ODBC 连接到 MySQL 数据库?

    我有一个新安装的 MySQL 服务器 它监听 localhost 3306 从 Qt 应用程序连接到它的正确方法是什么 原来我需要将MySQL添加到ODBC数据源 我在遵循这个视频教程后做到了这一点 https youtu be K3GZi

随机推荐

  • 如何根据组合框选择更改多个标签?

    我希望你知道如何根据不同的标签在不同的标签中拥有多个值Combobox下拉列表选择 例如 假设您有一个Combobox与值 car house computer 和多个Label选择时反映不同尺寸和颜色Combobox 如果我选择car 我
  • 极坐标图在 matplotlib 中给出错误的角度

    我正在尝试用Python绘制赤经 赤纬极坐标图 其中角度表示赤经 半径表示赤纬 范围在 30之间 我的代码是 import numpy import matplotlib pyplot as pyplot ra 345 3895474541
  • 无论如何,保持导航栏中的 Bootstrap Dropdown 打开

    我有一个嵌套在导航栏中的下拉菜单 我在页面加载期间通过添加以下内容打开该菜单open类到li包含下拉菜单的元素 我希望无论用户单击什么内容或单击页面上的哪个位置 此菜单都保持打开状态 我尝试过在 Stackoverflow com 上找到的
  • 如果添加另一个数据流,解析器无法解析

    我正在尝试使用解析器来根据路由保存的给定参数检索数据 不幸的是 当我添加另一个数据流时 我的数据依赖于解析器 但实际上从未解析 如果我直接返回一个立即解析值 一切都会正常 我调试了这种情况 发现我收到了所有部分信息 但最终未能真正解决 这是
  • 使用 compgen 获取另一个命令的自动完成功能,使用哪个标志?

    我有一个自定义自动完成命令 称之为commandA in commandB我想窃取命令第一个参数的自动完成选项 因此 例如 commandA 的 argument1 的选项是 abcdef abcabc abc123 我想要类似的东西com
  • ActiveMQ 的 NoSuchMethodError

    java lang NoSuchMethodError org apache activemq thread TaskRunnerFactory setThreadClassLoader Ljava lang ClassLoader V a
  • 侧面加载即时应用程序失败:读取捆绑包超时

    无法使用 Android 模拟器来测试即时应用程序 每次我得到 侧面加载即时应用程序失败 读取捆绑包超时 我在用着 Android Studio 3 0 金丝雀 5 Emulator 运行 Android 6 0 API 级别 23 x86
  • 如何使用流畅的 NHibernate 将枚举映射为 int 值?

    问题确实说明了一切 默认情况下它映射为string但我需要它映射为int 我目前正在使用PersistenceModel如果这有什么区别的话 我可以设定我的惯例 Update发现从主干获取最新版本的代码解决了我的困境 定义这个约定的方式以前
  • 如何从自定义视图(NSView)中制作缩略图视图?

    如何制作缩略图视图 不是图像 形成自定义视图 NSView 如果自定义 NSView 的内容发生更改 缩略图视图也会发生更改 看起来像ibook作者 谢谢大家 https plus google com u 0 photos 1147559
  • 用于生成唯一 ID 的 iOS 硬件参数

    您好 我想使用任何设备硬件参数为 iOS 设备生成一个唯一的 ID 我不想使用 MAC 地址 因为 MAC 地址也有可能被更改 那么您能否告诉我是否有任何其他唯一的硬件参数可以用来生成唯一的 ID 我相信类似的事情this是普遍接受的 UU
  • 无法对已卸载的组件执行 React 状态更新。这是一个无操作

    这是控制台中的警告 警告 无法对已卸载的组件执行 React 状态更新 这是一个空操作 但它表明应用程序中存在内存泄漏 要修复此问题 请取消 useEffect 清理函数中的所有订阅和异步任务 这是我的代码 const index setI
  • 将大型 XML 文件拆分为 Hadoop 的可管理部分

    是否有一个输入类可以根据 Hadoop 中的树结构处理 多个 大型 XML 文件 我有一组具有相同架构的 XML 文件 但我需要将它们拆分为数据部分 而不是分解这些部分 例如 XML 文件为
  • NHibernate 和数据库连接故障转移?

    我正在使用 NHibernate 连接到旧的 RDBMS 系统 在高生产负载下 rdbms 服务失败 为了保持可用性 我们提供了故障转移 RDBMS 服务 有没有办法将 NHibernate 配置为在主连接关闭时使用故障转移连接字符串 附加
  • 如何在 C 中通过 execv() 执行进程时杀死进程及其所有子进程?

    我正在尝试实施一个timeout类似命令unix基于操作系统如下 int pid timer t timer id struct sigevent timer event struct itimerspec timer value void
  • 所有 Android 设备中的蓝牙 RSSI 值始终以 dBm 为单位?

    我是 Android 新手 我的应用程序使用蓝牙从小型称重传感器放大器接收数据 虽然在某些设备 三星设备 中 BT 信号强度 RSSI 会按预期变化 从短距离处的 20 左右到 10m 处的 80 左右 但在其他一些设备 至少是一款 LG
  • 无法使用 cpan 在 darwin 13.0.1 上安装 GD 模块

    我在尝试安装 GD 时遇到了困难 我正在运行 Mas OSX 10 9 2 darwin 13 0 1 当我运行这个时 cpan 1 gt 安装 GD perl MCPAN e shell 我收到以下错误 cpan 1 gt install
  • 使用 MinGW 和 libnoise 库的 Netbeans C++

    使用 netbeans 7 2 和最新版本的 MinGW 使用安装程序 我无法使用 libnoise 库 我正确地包含了头文件 自动完成确认了这一点 但是该库根本无法工作 有一个 lib 文件和一个 dll 我尝试了在项目 gt 属性 gt
  • 替换 xml 属性的正则表达式

    我有一个以下形式的 xml 文件
  • 有 MSBuild 替代方案吗?

    我是一名正在接受培训的学生 对 C 的经验很少 我们公司正在开发一个使用T4模板 C VS2010 的解决方案 生成的文件无法在 MSBuild 下编译 因为它依赖于 VS 我的任务是找到一个工具或库或 dll 文件或SDK 或任何可以在构
  • 在Qt5中绘制大量独立角色的最佳方法?

    我正在编写一个显示大量文本的应用程序 但它不是单词和句子 而是以 CP437 字符集显示的二进制数据 目前的形式 但我在绘制这些角色时遇到了问题 我需要一一绘制每个角色 因为稍后我想应用不同的颜色 这些字符也应该有透明的背景 因为稍后我想在