QT: генерировать гистограмму на безголовом сервере AMI. Не удается запустить X Display - PullRequest
0 голосов
/ 19 апреля 2019

Я выполняю некоторую обработку на сервере Amazon Linux EC2 AWS.Когда что-то идет не так, мне нужно отправить письмо с гистограммой.Я хочу сгенерировать гистограмму самостоятельно, и я делаю это с помощью QPainter и QImage.Я сейчас разрабатываю пример приложения для простого создания гистограммы.Поэтому я занимаюсь разработкой на своем ноутбуке и, когда у меня есть что-то, что работает, загружает код на сервер EC2 и компилирует его там.Затем запустите получившееся приложение на сервере.

Однако, вот икота.Когда я попытался нарисовать текст с помощью QPainter, программа на моем ноутбуке вылетает.Это потому, что я использую QCoreApplication вместо QApplication в моем main.cpp.

Поэтому я перехожу на QApplication, которая решает проблему.Я загружаю код на сервер и компилирую его.Затем, когда я пытаюсь запустить его, я получаю:

qt.qpa.screen: QXcbConnection: Could not connect to display 
Could not connect to any X display.

Это, конечно, потому что сервер безголовый.У меня вопрос: могу ли я установить на сервер что-то, что позволило бы мне в полной мере использовать возможности QPainter?

Редактировать:

Мой main.cpp

#include <QApplication>
#include "../../CommonClasses/DataAnalysis/BarGrapher/bargrapher.h"

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

    // Setup
    qreal W = 1024;
    qreal H = 768;

    // A fictional data set;
    QList<qreal> ds1;
    ds1 << 50 << 500 << 368 << 198;

    QStringList descs;
    descs << "Item 1";
    descs << "A somewhat long and complex description";
    descs << "Item 2";
    descs << "Item Another";

    // The actual bar graph
    BarGrapher bg;
    bg.configureGraphText(W,H,descs,"Some sort of label","The title of this damn thing");
    BarGrapher::DataSet ds;
    ds << ds1;
    QImage result = bg.generateGraph(ds);

    qWarning() << "ERROR" << bg.getError();

    result.save("mytest.png");
    qWarning() << "DONE";

    return a.exec();
}

Мой bargrapher.cpp

#include "bargrapher.h"

const qreal BarGrapher::PROYECTION_FACTOR = 0.707106;
const qreal BarGrapher::LEFT_MARGIN  = 0.1;
const qreal BarGrapher::RIGHT_MARGIN = 0.04;
const qreal BarGrapher::TOP_MARGIN   = 0.08;

BarGrapher::BarGrapher()
{

}


void BarGrapher::configureGraphText(qreal width, qreal height, const QStringList &xItems, const QString &ylabel, const QString &title){
    graphTitle = title;
    W = width;
    H = height;
    itemDescriptions = xItems;
    yAxisText = ylabel;
}


QImage BarGrapher::generateGraph(const DataSet &dataSet){

    QImage graph(W,H,QImage::Format_RGB888);
    error = "";

    // Making sure that the data is coherent.
    if (dataSet.isEmpty()){
        error = "No data was presented";
        return graph;
    }
    if (dataSet.size() > 2){
        error = "Cannot have more than two data sets, passed " + QString::number(dataSet.size());
        return graph;
    }

    qint32 numItems = dataSet.first().size();
    for (qint32 i = 0; i < dataSet.size(); i++){
        if (numItems != dataSet.at(i).size()){
            error = "All data sets must be the same size: " + QString::number(numItems) + " however data set " + QString::number(i) + " has " + QString::number(dataSet.at(i).size());
            return graph;
        }
    }

    if (!itemDescriptions.isEmpty()){
        if (numItems != itemDescriptions.size()){
            error = "The number of item descriptios (" + QString::number(itemDescriptions.size()) + ") must coincide with the numer of points in the data set (" + QString::number(numItems) + ")";
            return graph;
        }
    }
    else{
        for (qint32 i = 0; i < numItems; i++){
            itemDescriptions << QString::number(i);
        }
    }

    // The font to be used
    QFont textFont("Mono");
    textFont.setPixelSize(10);
    //QFont titleFont("Mono",16,QFont::Bold);

    // Calculating margins to get the effective graph area.
    qreal XAxisLength = (1.0 - LEFT_MARGIN - RIGHT_MARGIN)*W;
    qreal DW = XAxisLength/(qreal)(numItems);

    // Calculating the effective graph area due to the text items.
    qreal Th = 0.1*H;
    qreal GH = (1.0-TOP_MARGIN)*H - Th;
    qreal xOffset = LEFT_MARGIN*W;
    qreal yOffset = TOP_MARGIN*H;

    // --------------- Commence drawing -----------------------
    QPainter painter(&graph);

    // The background
    painter.setBrush(QBrush(QColor(226,226,226)));
    painter.drawRect(0,0,W,H);

    // Drawing the axis;
    QPen pen;
    pen.setColor(QColor(0,0,0));
    pen.setWidth(2);
    painter.setPen(pen);
    painter.setBrush(QBrush(Qt::black));

    painter.drawLine(xOffset,yOffset+GH,xOffset + XAxisLength,yOffset+GH);
    painter.drawLine(xOffset,yOffset,xOffset,yOffset+GH);

    // Drawing the X Axis text
    painter.setFont(textFont);
    for (qint32 i = 0; i < numItems; i++){
        QRectF rectF(xOffset + i*DW,yOffset+GH,DW,Th);
        painter.drawText(rectF,itemDescriptions.at(i));
    }

    return graph;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...