[Qt-interest] Background and borders for QTextTable Cells

Kenneth Beck nekkceb at comcast.net
Sun May 10 21:23:47 CEST 2009


This is my second post on the subject, i got no response to the first, 
so am trying again.
I started with the example program for writing a QTextDocument to an 
.odf file, and I would like to add alternatingRowColors (Like 
QTableView) and add grids or borders to each row as well. The example 
has neither, and below lists my attempts to find ways to do it, followed 
by the example program. If someone can just add alternatingRowColors and 
  borders to each cell, I would appreciate seeing how to do it!

There is no setting in QTextTableFormat or QTextBlockFormat for 
alternatingRowColors, so I tried to do this in each cell, using 
QTextCharFormat.setBackground, but that did not seem to have any effect, 
not matter what color I set. Setting Font characteristics did have 
effect, not not background.

Likewise, there is no setting in the QTextCharFormat for grids, but 
there is for QTextBlockFormat, but that had no effect. I tried using 
setBackground there as well, but no effect. Also, is is not totally 
clear from documentation what constitutes a block. If I apply the 
BlockFormat to my cursor while building the table, will that set things 
for the whole table (as implied by description of a block)? Can I set 
format for just the row I'm in, or just the column?

I am probably missing something conceptually here, can someone 
straighten me out?

Qt ver 4.5.0, Visual Studio, with the integration 1.4.3 and Windows XP SP3.

Here are the contents of the example program (copyright notices stripped 
to preserve space...)

Start with the .pro file:

HEADERS   = phonebillwriter.h
SOURCES   = main.cpp \
             phonebillwriter.cpp
TEMPLATE = app

//////Now the main.cpp file

#include <QtGui>

#include "phonebillwriter.h"

int main(int c, char **v) {
     QApplication app(c,v);


     PhoneBillWriter phoneBill("Thomas Zander");

     QDateTime dt(QDate(2008, 04, 01), QTime(9, 4, 31));
     qsrand(QDateTime().secsTo(QDateTime::currentDateTime()));

     for (int i=0; i < 10; ++i)
     {
     int rm=RAND_MAX;
     int qr=qrand();
         PhoneBillWriter::PhoneCall call;
         dt = dt.addSecs(qrand() >> 4);
         call.date = dt;
         call.duration = qrand() >> 6;
         call.cost = call.duration / 4;
         phoneBill.addPhoneCall(call);

         dt = dt.addSecs(call.duration);
     }

     QStringList months;
     months << "April" << "May" << "June" << "July" << "August" << 
"September"
            << "October" << "November" << "December" << "January" << 
"February"
            << "March";
     QList<int> callsPerMonth;
     callsPerMonth << 6 << 84 << 76 << 0 << 93 << 128 << 76 << 31 << 19 
<< 4 << 12 << 78;
     phoneBill.addPastUsageGraph(months, callsPerMonth, "Your past usage:");

     phoneBill.write("phonebill.odt");
}

/////// Now the phonebillwriter.cpp file:

#include "phonebillwriter.h"

PhoneBillWriter::PhoneBillWriter(const QString &clientName)
{
     m_document = new QTextDocument();
     m_cursor = QTextCursor(m_document);

     QTextCharFormat defaultFormat;
     defaultFormat.setFontPointSize(12);
     boldFormat = defaultFormat;
     boldFormat.setFontWeight(QFont::Bold);
     QTextCharFormat titleFormat = boldFormat;
     titleFormat.setFontPointSize(20);

     centerFormat.setAlignment(Qt::AlignHCenter);

     m_cursor.setBlockFormat(centerFormat);
     m_cursor.insertText(QString("Phone bill for %1\n").arg(clientName),
                         titleFormat);

     QTextTableFormat tableFormat;
     tableFormat.setCellPadding(5);
     tableFormat.setHeaderRowCount(1);
     tableFormat.setBorderStyle(QTextFrameFormat::BorderStyle_Solid);
     tableFormat.setWidth(QTextLength(QTextLength::PercentageLength, 100));
     m_cursor.insertTable(1, 3, tableFormat);
     m_cursor.insertText("Date", boldFormat);
     m_cursor.movePosition(QTextCursor::NextCell);
     m_cursor.insertText("Duration (sec)", boldFormat);
     m_cursor.movePosition(QTextCursor::NextCell);
     m_cursor.insertText("Cost", boldFormat);
}

PhoneBillWriter::~PhoneBillWriter()
{
     delete m_document;
}

void PhoneBillWriter::addPhoneCall(const PhoneBillWriter::PhoneCall &call)
{
     QTextTable *table = m_cursor.currentTable();
     if (! table)
         return;

     table->appendRows(1); // moves our cursor to the end of the doc...
     m_cursor.movePosition(QTextCursor::PreviousRow);
     m_cursor.movePosition(QTextCursor::NextCell);
     m_cursor.insertText(call.date.toString());
     m_cursor.movePosition(QTextCursor::NextCell);
     m_cursor.insertText(QString::number(call.duration));
     m_cursor.movePosition(QTextCursor::NextCell);

     QChar euro(0x20ac);
     m_cursor.insertText(QString("%1 %2").arg(euro).arg(call.cost / 
(double) 100, 0, 'f', 2));
}

void PhoneBillWriter::addPastUsageGraph(const QStringList &months,
               const QList<int> &values, const QString &subtext)
{
     const int columnSize = 40;
     int width = values.count() * columnSize;
     int max = 0;
     foreach (int x, values)
         max = qMax(max, x);

     int height = 0;
     QFont font;
     font.setPixelSize(columnSize / 2);
     QFontMetrics metrics(font);

     foreach (QString month, months)
         height = qMax(height, metrics.width(month));
     height += 120;

     QImage image(width, height, QImage::Format_Mono);
     image.fill(Qt::white);
     QPainter painter(&image);
     painter.setFont(font);

     QVector<Qt::BrushStyle> patterns;
     patterns << Qt::SolidPattern << Qt::Dense4Pattern;
     for (int index = 0; index < values.count(); ++index) {
         // Adjust scale to our 100 pixel tall region:
         int height = values[index] * 100 / max;
         painter.fillRect(index * columnSize,
             100 - height, columnSize, height,
             patterns[index % 2]);
     }

     painter.translate(3 * columnSize / 4, 110);
     painter.rotate(270);
     for (int index = 0; index < months.count(); ++index) {
         painter.drawText(-metrics.width(months[index]), 0, months[index]);
         painter.translate(0, columnSize);
     }
     painter.end();

     QTextCursor cursor(m_document);
     cursor.movePosition(QTextCursor::End);
     cursor.insertBlock();
     cursor.setBlockFormat(centerFormat);
     cursor.insertText(subtext, boldFormat);
     cursor.insertBlock();
     cursor.insertBlock();
     cursor.insertImage(image);
}

void PhoneBillWriter::write(const QString &fileName)
{
     QTextDocumentWriter writer(fileName);
     writer.write(m_document);
}

////// Finally, the phonebillwriter.h file:

#ifndef PHONEBILLWRITER_H
#define PHONEBILLWRITER_H

#include <QtGui>

class PhoneBillWriter {
public:
     PhoneBillWriter(const QString &clientName);
     ~PhoneBillWriter();

     struct PhoneCall {
         QDateTime date;
         int duration; // in seconds
         int cost; // in euro-cents
     };

     void addPhoneCall(const PhoneCall &call);

     void addPastUsageGraph(const QStringList &months, const QList<int> 
&values,
                            const QString &subtext);

     void write(const QString &fileName);

private:
     QTextBlockFormat centerFormat;
     QTextCharFormat boldFormat;
     QTextCursor m_cursor;
     QTextDocument *m_document;
};

#endif



More information about the Qt-interest-old mailing list