| Trolltech Home | Qt-interest Home | Recent Threads | All Threads | Author | Date | |
| All threads index page 3 | |
Hi, I'm working on KOffice and there we use points for the document coordinate system. We transform the document to the view system by using QPainter::scale() and the dpi information from X11Info for the scaling factors in order to match real world units on screen. So far, so good. But QPainter also makes implicitly use of X's dpi information. It converts the font's point size to pixels with this info. So, now we scale the font twice. Fonts in the UI and in our canvas will get different sizes (given an X dpi != 72 or 75). I tried to hardcode the dpi setting by reimplementing int QWidget::metric(PaintDeviceMetric metric) const, but it seems to be ignored. Example code attached. Could anyone explain me why it does not work? Any other ideas to prevent the double scaling (while keeping the text's correct position)? I already tried to rescale the point size by dividing it by the y dpi, but it looks so unclean and one would have to do it in many places. Regards, Stefan
#include <QApplication>
#include <QApplication>
#include <QMainWindow>
#include <QPainter>
class MainWindow : public QMainWindow
{
public:
void paintEvent( QPaintEvent* event )
{
Q_UNUSED( event );
QPainter painter( this );
painter.drawText( QPointF( 10., 20. ), "Hello" );
}
protected:
int metric( PaintDeviceMetric metric ) const
{
switch( metric )
{
case QPaintDevice::PdmDpiX:
case QPaintDevice::PdmDpiY:
case QPaintDevice::PdmPhysicalDpiX:
case QPaintDevice::PdmPhysicalDpiY:
return 72;
default:
break;
}
return QMainWindow::metric( metric );
}
};
int main(int argc, char **argv)
{
QApplication app(argc, argv);
MainWindow mainWin;
mainWin.show();
return app.exec();
}
Hi, Hi know that this is a faq, homewer i want to complete this faq with another request : * What is the best way for doing a single instance application ( answers from the newsgroups don't seem to be the way i want to ) * How i can do to make my 2 instance communicate ? In fact, i need to ask to first instance to open the file request by the second. Thanks, P@sNox, -- [ signature omitted ]
Hi, there are several ways for IPC. You could use shared memory or a file. I'd recommend QSingleInstanceApplication but as you said that doesn't satisfy you (probably an open-source user like I am, thus no access to the add-on classes :-). Regards, Thomas Nox PasNox schrieb: > Hi, > > Hi know that this is a faq, homewer i want to complete this faq with another > request : > > * What is the best way for doing a single instance application ( answers > from the newsgroups don't seem to be the way i want to ) > * How i can do to make my 2 instance communicate ? In fact, i need to ask to > first instance to open the file request by the second. > > Thanks, P@sNox, > > -- > To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx with "unsubscribe" in the subject or the body. > List archive and information: http://lists.trolltech.com/qt-interest/ > > -- [ signature omitted ]
besides that this has nothing to do with QT... Ill give you some feedback in the form of questions :-) Are the two instances always on the same machine? How do the two instances know about each other? How should they handle exceptions to the communication protocol? I have used TCP sockets for this, I have used a lightweight WWW server for this, I have used files on the local filesystem. I no longer create my own protocol, and rather simply use XML for it, but all these methods could use QT or not. Scott ________________________________ From: Nox PasNox [mailto:pasnox@xxxxxxxxx] Sent: Wed 1/17/2007 8:51 AM To: qt-interest@xxxxxxxxxxxxx Subject: Single Application Instance - Inter Application Messaging Hi, Hi know that this is a faq, homewer i want to complete this faq with another request : * What is the best way for doing a single instance application ( answers from the newsgroups don't seem to be the way i want to ) * How i can do to make my 2 instance communicate ? In fact, i need to ask to first instance to open the file request by the second. Thanks, P@sNox, -- [ signature omitted ]
Thanks about this methods that are not bad ! I will try to implement this methods. Cheers, P@sNox, Scott Aron Bloom wrote: > besides that this has nothing to do with QT... Ill give you some feedback > in the form of questions :-) > > Are the two instances always on the same machine? > How do the two instances know about each other? > How should they handle exceptions to the communication protocol? > > I have used TCP sockets for this, I have used a lightweight WWW server for > this, I have used files on the local filesystem. I no longer create my > own protocol, and rather simply use XML for it, but all these methods > could use QT or not. > > Scott > > > ________________________________ > > From: Nox PasNox [mailto:pasnox@xxxxxxxxx] > Sent: Wed 1/17/2007 8:51 AM > To: qt-interest@xxxxxxxxxxxxx > Subject: Single Application Instance - Inter Application Messaging > > > > Hi, > > Hi know that this is a faq, homewer i want to complete this faq with > another request : > > * What is the best way for doing a single instance application ( answers > from the newsgroups don't seem to be the way i want to ) > * How i can do to make my 2 instance communicate ? In fact, i need to ask > to first instance to open the file request by the second. > > Thanks, P@sNox, > > -- > To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx with > "unsubscribe" in the subject or the body. List archive and information: > http://lists.trolltech.com/qt-interest/ > > > > -- > To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx with > "unsubscribe" in the subject or the body. List archive and information: > http://lists.trolltech.com/qt-interest/ -- [ signature omitted ]
Stefan Nikolaus wrote: > I'm working on KOffice and there we use points for the document coordinate > system. We transform the document to the view system by using > QPainter::scale() and the dpi information from X11Info for the scaling > factors in order to match real world units on screen. What exactly do you pass to QPainter::scale() and how do you calculate the scaling factors? > So far, so good. But QPainter also makes implicitly use of X's dpi > information. > It converts the font's point size to pixels with this info. Yes, it needs the information for each specific device to do this. > So, now we scale the font twice. Yes, it would appear so but, if your original units are points, why aren't you using those when calling font rendering functions? > Fonts in the UI and in our canvas will > get different sizes (given an X dpi != 72 or 75). [...] > Any other ideas to prevent the double scaling (while keeping the text's > correct position)? I already tried to rescale the point size by dividing > it by the y dpi, but it looks so unclean and one would have to do it in > many places. I'm confused about the overall rendering model you're using. If you can supply code that illustrates the problem, it would be useful. It seems to me that, since you're specifying document measurements in points, you need to scale all these using the DPI information from QX11Info (or using the widget's own metrics) to obtain values you can use in pixel- based functions. If you are using font metrics, you need to pass the device to the QFontMetrics[F] constructor to ensure that measurements are correct for that device, but this normally only matters for tasks such as printing. David -- [ signature omitted ]
David Boddie wrote: > What exactly do you pass to QPainter::scale() and how do you calculate the > scaling factors? scale( QX11Info::appDpiX() / 72, QX11Info::appDpiY() / 72 ); These are pixel/point ratios (QX11Info gives us the pixels/inch and 1"=72pt). >> So, now we scale the font twice. > > Yes, it would appear so but, if your original units are points, why aren't > you using those when calling font rendering functions? The font size is set by using QFont::setPointSizeF(). Is this what you meant? > I'm confused about the overall rendering model you're using. If you can > supply code that illustrates the problem, it would be useful. Apply the above scaling factors to the code I posted. And then, use the same font and size as you specified in your UI (qtconfig or kcontrol). If you have X dpi values unequal 72 dpi (75 dpi), you'll notice, that the fonts have different sizes. The more deviation the worse. > It seems to me that, since you're specifying document measurements in > points, you need to scale all these using the DPI information from > QX11Info (or using the widget's own metrics) to obtain values you can use Correct. > in pixel- based functions. If you are using font metrics, you need to pass > the device to the QFontMetrics[F] constructor to ensure that measurements > are correct for that device, but this normally only matters for tasks such > as printing. I don't see the use case for QFontMetrics here. I want to set the font size, so that the font after the QPainter::scaling matches that of the UI. Stefan -- [ signature omitted ]
Stefan Nikolaus wrote: > David Boddie wrote: >> What exactly do you pass to QPainter::scale() and how do you calculate >> the scaling factors? > > scale( QX11Info::appDpiX() / 72, QX11Info::appDpiY() / 72 ); > > These are pixel/point ratios (QX11Info gives us the pixels/inch and > 1"=72pt). OK. Just out of interest, do the values returned by appDpiX() and appDpiY() correspond to the physicalDpiX() and physicalDpiY() of the widget? >>> So, now we scale the font twice. >> >> Yes, it would appear so but, if your original units are points, why >> aren't you using those when calling font rendering functions? > > The font size is set by using QFont::setPointSizeF(). Is this what you > meant? Yes. Since you're already scaling the painter's output, so that you can specify dimensions in points, you need to set the font size using setPixelSize() instead. Otherwise, as you noticed, the value you specify will be converted internally to a value (the pixel size) which would normally be used unscaled. You are then scaling that again using QPainter::scale(), causing the scaling to be applied twice. The problem with using setPixelSize() is that there's no way to get the precision you need for small font sizes. >> I'm confused about the overall rendering model you're using. If you can >> supply code that illustrates the problem, it would be useful. > > Apply the above scaling factors to the code I posted. And then, use the > same font and size as you specified in your UI (qtconfig or kcontrol). If > you have X dpi values unequal 72 dpi (75 dpi), you'll notice, that the > fonts have different sizes. The more deviation the worse. I'm not sure that you should really be trying to override the metrics of the widget like that, but maybe I've misunderstood what you're trying to achieve. You should be able to get what you want by scaling the painter's output (as you are doing) and pretending that the point size you supply is a pixel size (since it will be scaled by the painter). However, I think you might get better results when drawing text to avoid scaling for the actual text drawing operations, though I do realize that this might make the rendering model you have more complicated. > I don't see the use case for QFontMetrics here. I want to set the font > size, so that the font after the QPainter::scaling matches that of the UI. It's just another issue you may encounter later. David -- [ signature omitted ]
David Boddie wrote: > OK. Just out of interest, do the values returned by appDpiX() and > appDpiY() correspond to the physicalDpiX() and physicalDpiY() of the > widget? Yes, but they are used for both, physical and logical. > Yes. Since you're already scaling the painter's output, so that you can > specify dimensions in points, you need to set the font size using > setPixelSize() instead. Otherwise, as you noticed, the value you specify > will be converted internally to a value (the pixel size) which would > normally be used unscaled. You are then scaling that again using > QPainter::scale(), causing the scaling to be applied twice. No, by using the QFont::setPointSizeF method I specify the device independent size. And if I draw text with a QPainter and this font the pixel size has to obey to the paint device metrics, i.e. the font size should not use the X dpi setting in this case. And if I then scale it with the X dpi based factors, I expect the font being the same size as on unscaled painting on an unmodified (metrics) widget. Regards, Stefan -- [ signature omitted ]
On Wednesday 17 January 2007 17:41, Stefan Nikolaus wrote: > Hi, > > I'm working on KOffice and there we use points for the document coordinate > system. We transform the document to the view system by using > QPainter::scale() and the dpi information from X11Info for the scaling > factors in order to match real world units on screen. > > So far, so good. But QPainter also makes implicitly use of X's dpi > information. It converts the font's point size to pixels with this info. > So, now we scale the font twice. Fonts in the UI and in our canvas will get > different sizes (given an X dpi != 72 or 75). > > I tried to hardcode the dpi setting by reimplementing > int QWidget::metric(PaintDeviceMetric metric) const, > but it seems to be ignored. Example code attached. > > Could anyone explain me why it does not work? > > Any other ideas to prevent the double scaling (while keeping the text's > correct position)? I already tried to rescale the point size by dividing it > by the y dpi, but it looks so unclean and one would have to do it in many > places. Your observation is correct. QPainter::drawText() always scales text where the corresponding font is specified in points to the device's resolution. You have to agree that this is sensible behavior :) Your approach of overriding metric() doesn't work when you paint onto a widget because of double-buffering. With double-buffering enabled (by default) you actually end up painting into a pixmap (the backing store) and Qt will copy that onto the screen in one go when painting finished, to prevent flicker. If you set the Qt::WA_PaintOnScreen attribute on your widget you'll see that the metric() is used and you will also observe flicker. With the use of the low-level QTextLayout class to draw text on your widget/device you have full control over the conversion from points to device pixels. That's what Thomas is using in KWord's text bits, too (for variables in KoVariable and counters in KoTextDocumentLayout). I think it's the best approach. Alternatively you can do the points to pixel conversion entirely yourself and set a pixel size on the QFont object for use with QPainter::drawText. Simon
Attachment:
Attachment:
pgpG306tV9Dme.pgp
Description: PGP signature
Message 11 in thread
Simon Hausmann wrote:
> With the use of the low-level QTextLayout class to draw text on your
> widget/device you have full control over the conversion from points to
> device pixels. That's what Thomas is using in KWord's text bits, too (for
> variables in KoVariable and counters in KoTextDocumentLayout). I think
> it's the best approach. Alternatively you can do the points to pixel
> conversion entirely yourself and set a pixel size on the QFont object for
> use with QPainter::drawText.
I haven't checked the code in detail yet, but as far as I can see on screen,
it also scales the font twice. :(
I filed a bug meanwhile and attached a new test case, that shows a 36 pt
font aligned with a 36 pt line. I think, you have access to it ("[Issue
N147309] Fonts ignore paint device's metrics"). It does not take your
QTextLayout suggestion into account though.
Regards,
Stefan
--
[ signature omitted ]