Каирская и Qt интеграция

Я хочу использовать графическую библиотеку Cairo с Qt, но не могу найти документацию. Я просто хочу сделать графический интерфейс с Qt и использовать Cairo для рисования графики в окне Qt.

Благодарю.

5 ответов

Решение

Последняя версия Cairo поддерживает Qt, позволяя рисовать на поверхности, созданной с помощью cairo_qt_surface_create(QPainter *painter): вы можете просмотреть соответствующий заголовочный файл здесь. Там нет документации, потому что эта функция все еще экспериментальная и по умолчанию отключена (вы должны явно скомпилировать cairo, включив поддержку Qt с configure --enable-qt,

Qt Paint System - очень хорошая библиотека для рисования, основанная на векторах. И это уже там. Если вы выберете Qt в качестве своего инструментария GUI, он не станет легче.

Предостережение: это не будет ответом, который вы ищете.

Вы уверены, что хотите этого? Для чего? Это о написании QPaintDevice основанный на Каире? В Qt реализованы собственные графические примитивы, как и в Каире. Единственная причина, которую я вижу, в том, что вы не хотите, чтобы тяжелый слой Qt мешал вашей системе (встроенный?). Как будто вы пытаетесь использовать DirectFB-бэкэнд Cairo - но есть и такие вещи, как Qt-on-DirectFB. Однако обратите внимание, что такая реализация является дорогостоящей и не бесплатной без собственного набора кварков, таких как проблемы взаимодействия библиотек, печать из этого контекста, основанного на Каире, и т. Д. Я бы посоветовал вам сделать регулярный поиск в Google, чтобы определить, являются ли такие усилия / когда-либо были в процессе и очень тяжело взвесить все за и против, прежде чем пытаться сделать то же самое

Это может быть достигнуто этим грязным способом:

  1. Создайте поверхность изображения Каира, нарисуйте ее.
  2. Вызовите cairo_image_surface_get_data(), чтобы получить пиксели.
  3. Скопируйте изображение в виджет Qt.

Вот пример того, как это можно сделать:

      class CairoWidget: public QWidget
{
public:
  using QWidget::QWidget;

private:
  void paintEvent(QPaintEvent*)
  {
    auto const w(width()), h(height());
    QImage image(w, h, QImage::Format_RGB32);

    auto const surf(cairo_image_surface_create_for_data(image.bits(),
      CAIRO_FORMAT_RGB24, w, h, image.bytesPerLine()));
    auto const cr(cairo_create(surf));
    cairo_surface_destroy(surf);

    //
    cairo_set_source_rgb(cr, 1, 1, 1);
    cairo_paint(cr);
    cairo_scale(cr, w, h);

    //
    cairo_set_source_rgb(cr, 0, 0, 0);
    cairo_move_to(cr, 0, 0);
    cairo_line_to(cr, 1, 1);
    cairo_move_to(cr, 1, 0);
    cairo_line_to(cr, 0, 1);
    cairo_set_line_width(cr, .2);
    cairo_stroke(cr);

    cairo_rectangle(cr, 0, 0, .5, .5);
    cairo_set_source_rgba(cr, 1, 0, 0, .80);
    cairo_fill(cr);

    cairo_rectangle(cr, 0, .5, .5, .5);
    cairo_set_source_rgba(cr, 0, 1, 0, .60);
    cairo_fill(cr);

    cairo_rectangle(cr, .5, 0, .5, .5);
    cairo_set_source_rgba(cr, 0, 0, 1, .40);
    cairo_fill(cr);

    cairo_destroy(cr);

    //
    QPainter p(this);
    p.drawImage(0, 0, image);
  }
};

int main(int argc, char* argv[])
{
  QApplication app(argc, argv);

  CairoWidget w;
  w.show();

  return app.exec();
}

Есть и другие хаки, которые вы можете попробовать, например рисование непосредственно в резервном хранилище или вы также можете инициализировать QImageиз вашего собственного буфера, что было бы предпочтительнее для пользовательского cairo QWidget:

      QImage::QImage(const uchar *data, int width, int height, int bytesPerLine, QImage::Format format, QImageCleanupFunction cleanupFunction = nullptr, void *cleanupInfo = nullptr)
Другие вопросы по тегам