I want to print rows of "QStandardItemModel". I use this code, It works but table is not beautiful.
I don't know how to adjust row height and I don't know how to set column widths based on the width of cells in the first row of the table.
QPrinter printer;
printer.setPageSize(QPrinter::A4);
printer.setFullPage(true);
QPrintDialog *dlg = new QPrintDialog(&printer,0);
if(dlg->exec() == QDialog::Accepted) {
QPainter painter;
if (painter.begin(&printer)) {
painter.translate(0,0);
int position = 0;
int rowCount=newMyModel->rowCount(QModelIndex());
for(int r=0;r<rowCount;r++)
{
if( position > painter.window().height()-100 )
{
printer.newPage();
position = 0;
painter.resetTransform();
painter.translate(0, 0);
}
QString html="<table style='page-break-after:always' border='1' width='100%' cellpadding =10 style='border-width: 1px;border-style: solid;border-color: #9e9e9e;width:100%'>";
index=newMyModel->index(r, 0);
QVariant prop1=index.data(MyModel::prop1);
QVariant prop2=index.data(MyModel::prop2);
'''
'''
'''
html.append(
"<tr style='background-color:red'>"
"<td style='border-width: 1px;padding:10; border-style: solid; border-color: #9e9e9e;width:16%'>"+prop1.toString()+" </td>"
"<td style='border-width: 1px;padding:10; border-style: solid; border-color: #9e9e9e;width:16%'>"+prop2.toString()+" </td>"
...
...
...);
}
html.append("</table>");
QRect rect = painter.boundingRect(painter.window(),
Qt::AlignJustify | Qt::TextWordWrap,
html);
QTextDocument doc;
doc.setHtml(html);
doc.drawContents(&painter, rect);
painter.drawRect(rect);
painter.translate(0, rect.height());
position += rect.height();
}
painter.end();
}
}
Related
I want to add a colored Widget over the full QStatusBar. I added a QLabel with red background-color but there is a padding around the label, which i can't remove.
what i tried:
setSizeGripEnabled(false)
setStyleSheet("QStatusBar { border: 0px; padding: 0px; margin: 0px; }"
"QStatusBar::item { border: 0px; padding: 0px; margin: 0px; }"
layout()->setContentsMargins(0, 0, 0, 0);
Update: Example Code:
QWidget *w = new QWidget;
QHBoxLayout *layout = new QHBoxLayout;
QStatusBar *statusBar = new QStatusBar;
QLabel *label = new QLabel("Example");
w->setStyleSheet("background-color: green");
label->setStyleSheet("background-color: red");
statusBar->addPermanentWidget(label, 1);
statusBar->layout()->setContentsMargins(0, 0, 0, 0);
statusBar->setSizeGripEnabled(false);
setStatusBar(statusBar);
w->setLayout(layout);
setCentralWidget(w);
}
I think it is not possible without pointer hacking or reimplementing all QStatusBar functionality because QStatusBar implementation based on pimpl idiom, which means some implementation hidden in private headers and borders between QStatusBar widget and children widgets are hardcoded in qstatusbar.cpp
QRect ir = item->w->geometry().adjusted(-2, -1, 2, 1);
...
QStyleOption opt(0);
opt.rect = ir;
...
style()->drawPrimitive(QStyle::PE_FrameStatusBarItem, &opt, &p, item->w);
QStatusBar{
min-height: 20px;
}
use the min-height css property.
I am generating html report with QTextDocument, my problem it comes when it should print each table on its own page, but it doesn't. I tried to use QPainter along with QTextDocument::drawContents() but this makes it show only the first page.
Another attempt was to insert a div and set its style to page-break-after:auto even it is supported by QTextDocument web engine, but this didn't work too.
void SemesterResultsReport::printDivisionStudentsNotes() {
QMap<int, int> divisionsList = SemesterResultsReport::getSelectedDivisions();
QPrinter *printer = new QPrinter(QPrinter::ScreenResolution);
printer->setFullPage(true);
printer->setResolution(90);
printer->setPaperSize(QPrinter::A4);
printer->setOrientation(QPrinter::Landscape);
printer->setPageMargins(5, 5, 5, 5, QPrinter::Millimeter);
/*printer->setOutputFormat(QPrinter::PdfFormat);
printer->setOutputFileName("sdf.pdf");*/
QPrintPreviewDialog *dlg = new QPrintPreviewDialog(printer, this);
connect(dlg, SIGNAL(paintRequested(QPrinter *)), this, SLOT(printOrder(QPrinter *)));
dlg->exec();
}
void SemesterResultsReport::printOrder(QPrinter *printer) {
QString strStream;
QTextStream out(&strStream);
QSqlQuery studentInfo, studentNotes;
QSqlRecord studentInfoRec, studentNotesRec;
QMap<int, int> selectedDivisions = SemesterResultsReport::getSelectedDivisions();
QMap<int, int>::const_iterator divisionId;
QTextDocument *document = new QTextDocument();
QTextCursor cursor(document);
QTextOption options;
options.setTextDirection(Qt::RightToLeft);
QSizeF paperSize;
paperSize.setWidth(printer->width());
paperSize.setHeight(printer->height());
document->setDefaultTextOption(options);
document->setPageSize(paperSize);
int mat_div = 0;
int level = 0;
int semester = ui.semestersList->currentText().toInt();
int school_year = 2015;
int numMaterials = 0;
// Report
out << "<!DOCTYPE html>"
<< "<html>\n"
<< "<head>"
<< "<title>ff</title>"
<< "<meta http-equiv=\"Content-Type\" content =\"text/html;charset=utf-8\" >"
<< "<style type=\"text/css\"> "
<< " html, body { margin: 5px; direction: rtl; width: 100% !important; align: right !important; float: right !important; }"
<< " *, p { font-family: \"Times New Roman\"; font-size: 16px; }"
<< " img { display: block; margin: 0 auto; }"
<< " p.title { font-weight: bold; font-size: 22px; align: center !important; }"
<< " table { border: 1; border-collapse: collapse; page-break-after:auto !important; width: 100% !important; align: right !important; float: right !important; }"
<< " th, td { border: 1px solid #000; padding: 0; align: center; page-break-inside:avoid; page-break-after:auto; }"
<< " tr { page-break-inside:avoid; page-break-after:auto !important; }"
<< " thead { display:table-header-group; }"
<< " tfoot { display:table-footer-group; }"
<< " .pagebreak { page-break-after:auto !important; } "
<< "</style>"
<< "</head>"
<< "<body>";
for (divisionId = selectedDivisions.constBegin(); divisionId != selectedDivisions.constEnd(); ++divisionId) {
mat_div = divisionId.key();
level = divisionId.value();
numMaterials = 0;
// Report header, get division materials to set as header
QStringList divisionMaterialsNames = SemesterResultsReport::getDivisionMaterialsNames(mat_div, level, school_year);
out << "<table float=\"right\" border=1 cellspacing=0 cellpadding=2>";
numMaterials = divisionMaterialsNames.size();
out << "<thead><tr bgcolor=#f0f0f0>";
for (int i = numMaterials - 1; i > -1; --i) {
out << "<th>" + divisionMaterialsNames[i] + "</th>";
}
out << "<th>" + QString("الإسم") + "</th>"
<< "<th>" + QString("اللقب") + "</th>"
<< "<th>" + QString("الرقم التسلسلي") + "</th>"
<< "</tr></thead>";
// Echo student info plus materials notes
QString fullName = ", fname, lname";
QString infoQuery = "SELECT Student.mat_stud as matStud" + fullName + " FROM Student, Class, Division WHERE Class.mat_div = Division.mat_div AND Class.mat_class = Student.mat_class AND school_year = " + QString::number(school_year) + " AND Class.level = " + QString::number(level) + " AND Division.mat_div = " + QString::number(mat_div);
studentInfo.exec(infoQuery);
studentInfoRec = studentInfo.record();
fullName.clear();
infoQuery = "SELECT Student.mat_stud as matStud FROM Student, Class, Division WHERE Class.mat_div = Division.mat_div AND Class.mat_class = Student.mat_class AND school_year = " + QString::number(school_year) + " AND Class.level = " + QString::number(level) + " AND Division.mat_div = " + QString::number(mat_div);
QString notesQuery = "SELECT materials_notes FROM Notes WHERE mat_stud IN (" + infoQuery + ") AND school_year = " + QString::number(school_year) + " AND level = " + QString::number(level) + " AND mat_div = " + QString::number(mat_div) + " AND semester = " + QString::number(semester);
studentNotes.exec(notesQuery);
studentNotesRec = studentNotes.record();
QStringList studentNotesList;
while (studentInfo.next()) {
out << "<tr>";
studentNotes.next();
studentNotesList = studentNotes.value(studentNotesRec.indexOf("materials_notes")).toString().split(",");
for (int i = 0; i < numMaterials; ++i) {
out << "<th>" + studentNotesList[i] + "</th>";
}
out << " <th>" + studentInfo.value(studentInfoRec.indexOf("lname")).toString() + "</th>"
<< " <th>" + studentInfo.value(studentInfoRec.indexOf("fname")).toString() + "</th>"
<< " <th>" + studentInfo.value(studentInfoRec.indexOf("matStud")).toString() + "</th>";
out << "</tr>";
}
// Close table tag, and insert new page, but it doesn't work
out << "</table><div style=\"page-break-after:auto !important;\"></div>";
}
// Finish report
out << "</body>"
<< "</html>";
/*
* Prepare QTextDocument
*/
document->setHtml(strStream);
document->print(printer);
// this makes only the first page printed
/*QPainter painter;
painter.begin(printer);
document->drawContents(&painter, printer->pageRect());
painter.end();*/
}
That is something like closable tabs in QTabBar.
Ready:::::::::::::::::::::
BtnWithClosing::BtnWithClosing(QString txt, QWidget *parent):
QPushButton(txt, parent) {
QHBoxLayout *layout = new QHBoxLayout;
layout->setMargin(4);
layout->setSpacing(0);
layout->setSizeConstraint(QLayout::SetMaximumSize);
setText(text() + " "); // for close button space
QPushButton *btnClose = new QPushButton;
btnClose->setStyleSheet("QPushButton:hover {image:"
"url(:/images/closebtnover.png);}"
"QPushButton {image: url(:/images/closebtn.png); margin-right: -9;"
"margin-left: -6; min-width: 0; background-color: transparent;"
"min-height: 0; border-width: 0px; border-radius: 9px; padding: 0px;}");
layout->addWidget(btnClose, 0, Qt::AlignRight);
setLayout(layout);
}
Here is part of the code, when sending x=0 and y=0, it places the child item "text" in the (0,0) of the scene not relative to its parent !
void ClassA::putLabel(qreal x, qreal y, QString text, QGraphicsPolygonItem* parent) {
QGraphicsTextItem * io = new QGraphicsTextItem;
io->setParentItem(parent);
io->setPos(x, y);
io->setFlags(QGraphicsItem::ItemIgnoresTransformations);
//io->setHtml("<div style='font-size: 10px; padding: -2px; margin: -2px;'>" + text + "</div>");
io->setFont(QFont("Helvetica", 8));
io->setPlainText(text);
}
Is it possible to set a common gradient for all QProgressBar chunks?
If use something like this:
QProgressBar::chunk:horizontal {
background: qlineargradient(x1: 0, y1: 0.5, x2: 1, y2: 0.5,
stop: 0 green,
stop: 1 white);
margin-right: 2px;
width: 10px;
}
the result will be
http://labs.trolltech.com/blogs/wp-content/uploads/2007/06/progressbar_righttext.png
but I want to obtain a one gradient, stretched to all chunks. Like this:
http://labs.trolltech.com/blogs/wp-content/uploads/2007/06/progressbar_nochunk.png
divided onto chunks.
Thanks for all!
You must only remove:
QProgressBar::chunk:horizontal {
background: qlineargradient(x1: 0,
y1: 0.5,
x2: 1,
y2: 0.5,
stop: 0 green,
stop: 1 white);
margin-right: 2px;
width: 10px; // <------ remove this propierty
}
You cannot achieve what you want with the existing stylesheet properties. You could however subclass QProgressBar and reimplement the paint in order to get the appearance you wish.
something like this would work, but I'd prefer subclassing QProgressBar as webclectic said
class Wrapper : public QWidget
{
Q_OBJECT
QProgressBar *progressBar ;
QSlider *slider ;
public :
Wrapper(void) : QWidget(), progressBar(new QProgressBar), slider(new QSlider(Qt::Horizontal))
{
progressBar->setMinimum(0) ;
progressBar->setMaximum(100) ;
slider->setMinimum(0) ;
slider->setMaximum(100) ;
QVBoxLayout *l = new QVBoxLayout ;
setLayout(l) ;
l->addWidget(progressBar) ;
l->addWidget(slider) ;
slider->setValue(0) ;
connect(slider, SIGNAL(valueChanged(int)), SLOT(slider_value_changed(int))) ;
slider_value_changed(0) ;
}
protected slots :
void slider_value_changed(int new_value)
{
QString updated_bg = QString("background: qlineargradient(x1: 0, y1: 0.5, x2: 1, y2: 0.5, stop: 0.0 green, stop: %0 white, stop: 1.0 white);").arg(new_value/100.0) ;
QString style_sheet ;
style_sheet += QString("QProgressBar {"
"%0"
"border: 2px solid grey;"
"border-radius: 5px;"
"text-align: center;"
"}").arg(updated_bg) ;
style_sheet += "QProgressBar::chunk {"
"background: transparent;"
"width: 10px;"
"margin: 0.5px;"
"}" ;
progressBar->setStyleSheet(style_sheet) ;
progressBar->setValue(new_value) ;
}
} ;
int main( int argc, char **argv )
{
QApplication app(argc, argv) ;
Wrapper w ;
w.show() ;
return app.exec() ;
}