I am not able to draw path using QPainter drawText() method
QString Path = "/home/User"
QPainter *painter
QRectF centerRect = QRectF (textX,centerY + m_bounds.height()*0.15, fm.width(Path),fm.height());
painter->drawText(centerRect,Path,QTextOption(Qt::AlignCenter | Qt::AlignHCenter ));
In windows its drawing the text but on ubunthu Linux its showing only /home
QFontMetrics fm = painter->fontMetrics();
qreal centerY = ( m_bounds.height() - fm.height() -10 )/2;
qreal textX = 8;
QRectF centerRect = QRectF (textX,centerY + m_bounds.height()*0.15, fm.width(m_folderPath),fm.height());
painter->drawText(centerRect,m_folderPath,QTextOption(Qt::AlignCenter | Qt::AlignHCenter ));
fm.width(m_folderPath)
shows differnet value for /home/user and /homeuser4
Related
I need to draw triangle shape and rhombus shapes like this image.In this code which design triangle shape (figure 1) but I need to add this shape to text "TRI" . And I also need to implement this code to design rhombus shape like (figure 2). please help me to solve this.
Figure 1
void MainWindow::on_btnTri_clicked()
{
QPen redPen(Qt::black);
redPen.setWidth(2);
QRectF rect = QRectF(0, 0, 200, 200);
QPainterPath path;
path.moveTo(rect.left() + (rect.width() / 2), rect.top());
path.lineTo(rect.bottomLeft());
path.lineTo(rect.bottomRight());
path.lineTo(rect.left() + (rect.width() / 2), rect.top());
QGraphicsPathItem* item = ui->graphicsView->scene()->addPath(path, redPen);
item->setFlag(QGraphicsItem::ItemIsMovable, true);
item->setFlag(QGraphicsItem::ItemIsSelectable,true);
}
Figure 2 I use this code to design figure 2 But which cannot pass parameters to change there size,My figure 1 designed code I can able pass two parameters to QRectF(0, 0, para1, para2); this for change triangle's size.so I need to change this code to do the same thing using QPainterPath or any other way.
void MainWindow::on_btnRomb_clicked()
{
QPolygonF romb;
romb.append(QPointF(20,40));
romb.append(QPointF(0,20));
romb.append(QPointF(20,0));
romb.append(QPointF(40, 20));
QGraphicsPolygonItem* itemR = ui->graphicsView->scene()->addPolygon(romb);
itemR->setFlag(QGraphicsItem::ItemIsMovable);
}
you must use the addText() method of QPainterPath, to place it in the center you must calculate the width and height of the text for it QFontMetrics is used:
QPen redPen(Qt::black);
redPen.setWidth(2);
QRectF rect(0, 0, 200, 200);
QPainterPath path;
path.moveTo(rect.left() + (rect.width() / 2), rect.top());
path.lineTo(rect.bottomLeft());
path.lineTo(rect.bottomRight());
path.lineTo(rect.left() + (rect.width() / 2), rect.top());
path.moveTo(rect.center());
QFont font("Times", 20, QFont::Bold);
QFontMetrics fm(font);
QString text = "TRI";
QSize size = fm.size(Qt::TextSingleLine, text);
path.addText(rect.center()+ QPointF(-size.width()*0.5, size.height()*0.5), font, text);
QGraphicsPathItem *item = ui->graphicsView->scene()->addPath(path, redPen);
item->setFlag(QGraphicsItem::ItemIsMovable, true);
item->setFlag(QGraphicsItem::ItemIsSelectable,true);
For the case of the diamond you should only get the midpoints of each vertex:
QPainterPath path;
QRectF rect(0, 0 , 100, 100);
path.moveTo(rect.center().x(), rect.top());
path.lineTo(rect.right(), rect.center().y());
path.lineTo(rect.center().x(), rect.bottom());
path.lineTo(rect.left(), rect.center().y());
path.lineTo(rect.center().x(), rect.top());
QGraphicsPathItem* itemR = ui->graphicsView->scene()->addPath(path);
itemR->setFlag(QGraphicsItem::ItemIsMovable);
I am looking for an effective way to use the drawText method of QPainter according to a QRect. For example if I were to have a QRect as the origin with a size of 50x50: QRect(0, 0, 50, 50); and wanted to fit text so it fits from left to right. Here are a few of the examples that I currently have, but to no extent can I get them to move fluently.
Example 1:
font.setStyleHint(QFont::AnyStyle, QFont::PreferAntialias);
painter.setRenderHint(QPainter::TextAntialiasing);
QStyleOptionGraphicsItem option;
qreal lod = option.levelOfDetailFromTransform(painter.worldTransform());
QRectF r = textRect;
QFont f = font;
qreal aspectRatio = painter.fontMetrics().lineSpacing() / painter.fontMetrics().averageCharWidth();
int pixelsize = sqrt(r.width() * r.height() / aspectRatio / (m_text.length() * 3)) * aspectRatio;
f.setPixelSize(pixelsize);
int flags = Qt::AlignCenter | Qt::TextDontClip | Qt::TextWordWrap;
if ((pixelsize * lod) < 13)
flags |= Qt::TextWrapAnywhere;
QFontMetricsF fm(f);
QRectF tbr = fm.boundingRect(r, flags, m_text);
pixelsize = f.pixelSize() * qMin(r.width() * 0.65 / tbr.width(), r.height() * 0.65 / tbr.height());
f.setPixelSize(pixelsize);
painter.setFont(f);
painter.drawText(r, flags, m_text);
However this leaves me with jittery text that is not smooth.
Example 2:
float factor = (rectangle.width() / painter.fontMetrics().width(m_text))/2;
if ((factor < 1) || (factor > 1.25))
{
font.setPointSizeF(font.pointSizeF()*factor);
painter.setFont(font);
}
QPainterPath textPath;
textPath.addText(textRect.topLeft(), font, m_text);
painter.drawPath(textPath);
Example 3:
QImage image(size(), QImage::Format_ARGB32_Premultiplied);
{
QPainter p(&image);
p.setRenderHint(QPainter::TextAntialiasing);
QFont font;
font.setFamily("Roboto medium");
font.setPointSize((double)scalar/10);
font.setStyleHint(QFont::Helvetica, QFont::PreferAntialias);
p.setPen(Qt::black);
p.setFont(font);
p.drawText(rect(), Qt::AlignLeft , m_text);
}
painter.drawImage(rectangle, image);
Honestly I am using these method to make circular buttons that can either have text, text+icon, or just an icon. I would like them to be scalable. Any method that can do as such would be greatly appreciated. Thank you very much.
I'm trying draw some rhombuses with random colors in a QWidget. And i want to save the current QWidget as image. I use such code to do this:
QPixmap pixmap(this->size());
this->render(&pixmap);
pixmap.save("test.png");
The problem is that the render() seems to call paintEvent again, and the paintEvent will draw the rhombuses with new random colors, so that i always get a different Image saved compared to the image displayed. Can someone tell me how to save the current QWidget? Thanks in advance.
Code for drawing rhombuses:
void Dialog::paintEvent(QPaintEvent *e) {
QPainter painter(this);
QRect background(0,0,this->geometry().width(),this->geometry().height());
painter.setBrush( QBrush( Qt::white ) );
painter.setPen( Qt::NoPen );
//QBrush bbrush(Qt::black,Qt::SolidPattern);
painter.drawRect(background);
int width = this->geometry().width();
int height = this->geometry().height();
//draw rectangles
int rec_size=64;
int rows=0;
int cols=0;
rows=floor((double)height/(double)rec_size);
cols=floor((double)width/(double)rec_size);
QPointF points[4]; // QRect rec(0,0,rec_size,rec_size);
for (int i=0;i<floor(rows);i++){
for (int j=0;j<floor(cols);j++){
painter.setBrush( QBrush( colors[rand() % color_size] ) );
//QPainter painter(this);
points[0] = QPointF(rec_size*(j),rec_size*(i+0.5));
points[1] = QPointF(rec_size*(j+0.5),rec_size*(i));
points[2] = QPointF(rec_size*(j+1),rec_size*(i+0.5));
points[3] = QPointF(rec_size*(j+0.5),rec_size*(i+1));
painter.drawPolygon(points, 4);
}
}
painter.end();
}
You can have a class member variable of boolean type to check in the paintEvent whether a random color should be used. Also a variable to save the index of the last color used is necessary:
bool isRandom;
int lastColor;
The paintEvent should be like :
void Dialog::paintEvent(QPaintEvent *e) {
...
if(isRandom)
{
lastColor = rand() % color_size;
painter.setBrush( QBrush( colors[lastColor] ) );
}
else
painter.setBrush( QBrush( colors[lastColor] ) );
...
}
The variable has true when drawing the widget regularly. When you want to save it's image, assign the variable to false, save the image and assign it to true again :
isRandom = false;
QPixmap pixmap(this->size());
this->render(&pixmap);
pixmap.save("test.png");
isRandom = true;
If the size of the page is same, then no problem, but I need the page size should be the size of Image(which is variable),
void DgJpgToPdf::convertToPdf( const QStringList& theImagePathList, const QString& theOutputFileName )
{
QPrinter printer;
printer.setOrientation(QPrinter::Portrait);
printer.setOutputFormat( QPrinter::PdfFormat );
printer.setOutputFileName( theOutputFileName );
QPainter painter;
painter.begin( &printer );
//printer.newPage();
foreach( QString fileName, theImagePathList ){
QImage imgObj( fileName );
printer.setPaperSize( QSizeF(imgObj.width(), imgObj.height()), QPrinter::DevicePixel );
painter.drawImage( 0, 0, imgObj );
printer.newPage();
}
painter.end();
}
You may wish to use QPdfWriter rather than QPrinter. You'll have to pick a PPI for the image, but if you want to save at 96 PPI, you could do something like
QPdfWriter pdfWriter(theOutputFileName);
pdfWriter.setTitle(theDocumentTitle);
pdfWriter.setCreater(yourApplicationName);
const qreal horizontalMarginMM = 2.0; // 2mm margin on each side
const qreal verticalMarginMM = 2.0;
QPagedDevice::Margins margins;
margins.left = margins.right = horizontalMarginMM;
margins.top = margins.bottom = verticalMarginMM;
pdfWriter.setMargins(margins);
bool newPage = false;
QPainter painter;
painter.begin(&pdfWriter);
foreach (const QString& fileName, theImagePathList) {
QImage imageObj(fileName);
if (newPage)
pdfWriter.newPage();
newPage = true;
qreal pageWidthMM = imgObj.width() / 96.0 * 25.4 + 2*horizontalMarginMM;
qreal pageHeightMM = imgObj.height() / 96.0 * 25.4 + 2*verticalMarginMM;
imgObj.setDotsPerMeterX(96.0 / 25.4 * 1000.0);
imgObj.setDotsPerMeterY(96.0 / 25.4 * 1000.0);
pdfWriter.setPageSizeMM(QSizeF(pageWidthMM, pageHeightMM));
painter.drawImage(0, 0, imageObj);
}
painter.end();
Using QT, how would I go about taking user-supplied input (text) and drawing the font in such a way that it "follows" a circular path?
I really know nothing at all about QT but if I understood your question right, I found the solution with a simple google search. Code is below and here is the source link:
http://developer.qt.nokia.com/faq/answer/how_do_i_make_text_follow_the_line_curve_and_angle_of_the_qpainterpath
#include <QtGui>
#include <cmath>
class Widget : public QWidget
{
public:
Widget ()
: QWidget() { }
private:
void paintEvent ( QPaintEvent *)
{
QString hw("hello world");
int drawWidth = width() / 100;
QPainter painter(this);
QPen pen = painter.pen();
pen.setWidth(drawWidth);
pen.setColor(Qt::darkGreen);
painter.setPen(pen);
QPainterPath path(QPointF(0.0, 0.0));
QPointF c1(width()*0.2,height()*0.8);
QPointF c2(width()*0.8,height()*0.2);
path.cubicTo(c1,c2,QPointF(width(),height()));
//draw the bezier curve
painter.drawPath(path);
//Make the painter ready to draw chars
QFont font = painter.font();
font.setPixelSize(drawWidth*2);
painter.setFont(font);
pen.setColor(Qt::red);
painter.setPen(pen);
qreal percentIncrease = (qreal) 1/(hw.size()+1);
qreal percent = 0;
for ( int i = 0; i < hw.size(); i++ ) {
percent += percentIncrease;
QPointF point = path.pointAtPercent(percent);
qreal angle = path.angleAtPercent(percent);
qreal rad =qreal(0.017453292519943295769)*angle; // PI/180
// From the documentation:
/**
QTransform transforms a point in the plane to another point using the following formulas:
x' = m11*x + m21*y + dx
y' = m22*y + m12*x + dy
**/
// So the idea is to find the "new position of the character
// After we apply the world rotation.
// Then translate the painter back to the original position.
qreal sina = std::sin(rad);
qreal cosa = std::cos(rad);
// Finding the delta for the penwidth
// Don't divide by 2 because some space would be nice
qreal deltaPenX = cosa * pen.width();
qreal deltaPenY = sina * pen.width();
// Finding new posision after rotation
qreal newX = (cosa * point.x()) - (sina * point.y());
qreal newY = (cosa * point.y()) + (sina * point.x());
// Getting the delta distance
qreal deltaX = newX - point.x();
qreal deltaY = newY - point.y();
// Applying the rotation with the translation.
QTransform tran(cosa,sina,-sina,cosa,-deltaX + deltaPenX,-deltaY - deltaPenY);
painter.setWorldTransform(tran);
painter.drawText(point,QString(hw[i]));
}
}
};
int main(int argc, char **argv)
{
QApplication app(argc, argv);
Widget widget;
widget.show();
return app.exec();
}