#qt #amazon-ec2
#qt #amazon-ec2
Вопрос:
Я выполняю некоторую обработку на сервере 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 amp;xItems, const QString amp;ylabel, const QString amp;title){
graphTitle = title;
W = width;
H = height;
itemDescriptions = xItems;
yAxisText = ylabel;
}
QImage BarGrapher::generateGraph(const DataSet amp;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(amp;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;
}
Комментарии:
1. Пожалуйста, покажите свой код. Ошибки, которые вы видите, — это то, что я мог бы ожидать, если бы вы пытались использовать a
QPixmap
, а не aQImage
.2. Добавлен полный код. Но я не использую QPixmap. И проблема, на мой взгляд, связана с тем фактом, что для рисования текста требуется «подключение» (не знаю, как это описать) к оконной системе, которой нет на сервере Amazon
3. Извините, я немного неправильно истолковал вопрос. Можете ли вы объяснить, что происходит, когда вы используете
QCoreApplication
вместоQApplication
— это, кажется, работает нормально для меня.4. Я делаю? Моя программа завершает работу с painter.DrawText (RectF,itemDescriptions.at (i));
5. попробуйте использовать QGuiApplication вместо QApplication.