Qt World Summit: Submit your Presentation

Handle pixel density in css.

  • Hello,

    I have a QT application which uses stylesheets heavily. It should maintain size across various pixel density displays. I read somewhere that using pt instead of px as units would scale graphics to physical size but this did not work.

    The only other solution I can think of is getting the physicalDotsPerInch property from the display and manually parse my stylesheets to scale all the pixel sizes. This is far from ideal due to obvious performance reasons.

    Would anyone happen to know the "proper" way to handle high dpi displays?

    Thanks alot.

  • In the end it seems there is no better way, I ended up modifying my css at runtime.
    For others strugling with this, heres how i did it:

    QString cssScale(QString text)
    	QRegExp regex("\[([0-9]+)\]");
    	int index;
    	while((index = text.indexOf(regex)) != -1)
    		text.remove(index, regex.cap(0).length());
    		text.insert(index, QString::number(
    	return text;

    You can get dpi_factor like this:

    double dpi_factor = QApplication::primaryScreen()->physicalDotsPerInch()/109;

    109 is the dpi where your css works without modification.

    Then you can write css like this

    width: [5]px;

    and the [5] will be replaced by a size scaled to the screen.

    Its not ideal but it works.

  • Lifetime Qt Champion


    A more simple solution would be to write your style sheet with placeholder to the value you want to change so you can use QString's arg method to put the correct values in place.

    QString styleSheet("width: %1").arg(width);

    Hope it helps

    [edit: Fixed code following @mcosta correction SGaist]

  • Hi,

    little correction. The right syntax should be

    QString styleSheet("width: %1").arg(width);

    in QString::arg() placeholders shall be in the range 1-99

  • Lifetime Qt Champion

    @mcosta Right ! Python's influence :D

  • @SGaist I know, Python sometimes brakes C++ skills :D

  • @SGaist Thanks for the response.

    I just don't quite understand the following:
    A: How this works with arbitrary style sheets(different amounts of values to be replaced)?
    B: Can I only replace up to 100 unique sizes?
    C: Where does the initial value for width come from(the one I will multiply with dpi_factor)?

    Also would this method be more efficient performance wise?... I am running a lot of css through this function.

    Thanks again.

  • CSS lets you use relative length units, see this:

    As suggested in that link before, em and rem create perfectly scalable sizes. Don't let the name and description fool you: although the size refers to the size of the M character, they can be applied to width, height and any other CSS property as well.

    Also, if you use a main CSS class like this:

    main_class { width: 1em; height: 1em; font-size: 10em; }

    and all the other objects (or CSS styles) are childs of this class:

    main_class.div { .... }
    // or something like this in HTML
    <BODY class="main_class">
        <div class="other_class">something</div>
    // in C++ the BODY widget would the parent of the div widget

    You can then only change the main_class sizes, and all the child items of that class will scale accordingly to their parent. Suppose you have this CSS for that div element before:

    other_class { width: 10em; height: 4em; font-size: 1.3em; }

    and suppose that the main_class CSS is this:

    main_class { width: 3em; height; 3m; font-size: 10em; }

    then the real sizes of that other_class are actually:

    width: 30 em;  // 3 * 10
    height: 12 em;  // 3 * 4
    font_size: 13 em; // 10 * 1.3

    because they have been scaled by 3, 3 and 10ems, respectively. Using ems is for sure the best way in CSS to scale items proportionally.

    I hope this helps :)