Rectangle不会覆盖整个ApplicationWindow

时间:2017-10-15 19:35:17

标签: android qml qt5 qtquick2 applicationwindow

图片说得比文字好(黑色矩形红色 ApplicationWindow):

enter image description here

注意顶部和右侧的红色未填充区域。右侧红色可能很难注意到,但它就在那里!我希望我用黑色着色的矩形填充整个应用程序窗口。见代码:

main.qml

import QtQuick 2.9
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.3

ApplicationWindow {    
    id: window
    visible: true

    /* Developing mobile apps you don’t need to set width
       and height, because the ApplicationWindow always grabs
       the total available space.
    */
    //width: 640
    //height: 480

    color: "#ff0000" // Red color

    /* For some reasons i want this Rectangle here
     * and it MUST fill the entire window but I notice
     * a pixel or two line on top and right of the
     * screen.
     */
    Rectangle {
        id: page
        width: window.width; height: window.height
        //anchors.fill: parent // same output
        color: "#000000" // Black color
    }
}

的main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;
    engine.load(QUrl(QLatin1String("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;

    return app.exec();
}

我不知道我在这里缺少什么:(

请分享此问题的解决方案/解决方法。

我也尝试了这个,但仍然是相同的输出:

import QtQuick 2.9
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.3
import QtQuick.Window 2.2

Window {  
    id: window
    visible: true

    height: Screen.height
    width: Screen.width

    /* Developing mobile apps you don’t need to set width
       and height, because the ApplicationWindow always grabs
       the total available space.
    */
    //width: 640
    //height: 480

    color: "#ff0000" // Red color

    /* For some reasons i want this Rectangle here
     * and it MUST fill the entire window but I notice
     * a pixel or two line on top and right of the
     * screen.
     */
    Rectangle {
        id: page
        width: window.width; height: window.height
        //anchors.fill: parent // same output
        color: "#000000" // Black color
    }
}

我注意到在main.cpp中注释后面的行解决了这个问题但是现在我想在UI中显示的所有小部件看起来都很小..!它们在小屏幕设备中看起来很好,而在大屏幕设备中看起来很小。 :(

QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

对此有何解决方案?

修改 这是一个已证实的错误,自近一年以来已被报道HERE! 。如果您遇到同样的问题,请登录https://bugreports.qt.io/并投票THIS错误。

1 个答案:

答案 0 :(得分:2)

好吧,你可以使用你自己的&#34; dp计算。

<强>的main.cpp

int density = 0;
float logicalDensity = 0;
float yDpi = 0; float xDpi = 0;

#if defined(ANDROID)
   QAndroidJniObject qtActivity = QAndroidJniObject::callStaticObjectMethod("org/qtproject/qt5/android/QtNative", "activity", "()Landroid/app/Activity;");
   QAndroidJniObject resources = qtActivity.callObjectMethod("getResources", "()Landroid/content/res/Resources;");
   QAndroidJniObject displayMetrics = resources.callObjectMethod("getDisplayMetrics", "()Landroid/util/DisplayMetrics;");
   density = displayMetrics.getField<int>("densityDpi");
   logicalDensity = displayMetrics.getField<float>("density");
   yDpi = displayMetrics.getField<float>("ydpi");
   xDpi = displayMetrics.getField<float>("xdpi");
   qDebug() << "Native Android Call =>>> | Logical Density: " << logicalDensity << " | DensityDPI: " << density << " | " << "++++++++++++++++++++++++";
#endif
[...]
// Set Android pixel data for QML context
engine.rootContext()->setContextProperty("densityData", density);
engine.rootContext()->setContextProperty("logicalDensityData",logicalDensity);
engine.rootContext()->setContextProperty("xDpiData",xDpi);
engine.rootContext()->setContextProperty("yDpiData",yDpi);

对于您的ApplicationWindow组件,请添加以下内容:

<强> main.qml

Component.onCompleted: {
        Units.pixelDensity = Qt.binding(function() {
            if (Qt.platform.os === "android") {
                return densityData / 25.4; // densityData is per inch but we need per mm
            }
            return Screen.pixelDensity
        });

        function calculateDiagonal() {
            if (Qt.platform.os === "android") {
                return Math.sqrt(Math.pow(Screen.width, 2) +
                                 Math.pow(Screen.height, 2)) / densityData;
            }
            return Math.sqrt(Math.pow(Screen.width, 2) +
                             Math.pow(Screen.height, 2)) / (Screen.pixelDensity * 25.4);
        }

        Units.multiplier = Qt.binding(function() {
            var diagonal = calculateDiagonal();
            Device.diagonal = diagonal;
            var baseMultiplier = 1;
            if (diagonal >= 3.5 && diagonal < 5.1) { //iPhone 1st generation to phablet
                return 0.8;
            } else if (diagonal >= 5.1 && diagonal < 6.5) {
                return 1;
            } else if (diagonal >= 6.5 && diagonal < 15.1) {
                return baseMultiplier;
            } else if (diagonal >= 15.1 && diagonal < 29) {
                return 1.4 * baseMultiplier;
            } else if (diagonal >= 29 && diagonal < 92) {
                return 1.4 * baseMultiplier;
            } else {
                return 1.4 * baseMultiplier;
            }
        });

        Device.type = Qt.binding(function () {
            var diagonal = calculateDiagonal();
            Device.diagonal = diagonal;
            if (diagonal >= 3.5 && diagonal < 5) { //iPhone 1st generation to phablet
                return Device.phone;
            } else if (diagonal >= 5 && diagonal < 7.2) {
                return Device.phone;
            } else if (diagonal >= 7.2 && diagonal < 15.1) {
                return Device.tablet;
            } else if (diagonal >= 15.1 && diagonal < 29) {
                return Device.desktop;
            } else if (diagonal >= 29 && diagonal < 92) {
                return Device.tv;
            } else {
                return Device.unknown;
            }
        });

        // Nasty hack because singletons cannot import the module they were declared in, so
        // the grid unit cannot be defined in either Device or Units, because it requires both.
        // See https://bugreports.qt.io/browse/QTBUG-39703
        Units.gridUnit = Qt.binding(function() {
            return Device.type === Device.phone || Device.type === Device.phablet
                    ? Units.dp(48) : Device.type == Device.tablet ? Units.dp(56) : Units.dp(64)
        });
}

<强> Units.qml

Object {
    id: units

    /*!
       \internal
       This holds the pixel density used for converting millimeters into pixels. This is the exact
       value from \l Screen:pixelDensity, but that property only works from within a \l Window type,
       so this is hardcoded here and we update it from within \l ApplicationWindow
     */
    property real pixelDensity: 4.46
    property real multiplier: 1.4 //default multiplier, but can be changed by user

    /*!
       This is the standard function to use for accessing device-independent pixels. You should use
       this anywhere you need to refer to distances on the screen.
     */
    function dp(number) {
        return Math.round(number*((pixelDensity*25.4)/160)*multiplier);
    }

    function gu(number) {
        return number * gridUnit
    }

    property int gridUnit: dp(64)
}

<强> Device.qml

import QtQuick 2.0

pragma Singleton

/*!
   \qmltype Device
   \inqmlmodule Material 0.1

   \brief A singleton that provides information about the current device.
 */
Object {
    id: device

    //some kind of enum, by screen size
    property int type: desktop
    property int diagonal: -1

    readonly property int phone: 0
    readonly property int phablet: 1
    readonly property int tablet: 2
    readonly property int desktop: 3
    readonly property int tv: 4
    readonly property int unknown: 5 //it's either bigger than tv or smaller than phone

    readonly property string name: {
        switch (type) {
            case 0:
                return "phone";
            case 1:
                return "phablet";
            case 2:
                return "tablet";
            case 3:
                return "computer";
            case 4:
                return "TV";
            case 5:
                return "device";
        }
    }

    readonly property string iconName: {
        switch (type) {
            case 0:
                return "hardware/smartphone";
            case 1:
                return "hardware/tablet";
            case 2:
                return "hardware/tablet";
            case 3:
                return "hardware/desktop_windows";
            case 4:
                return "hardware/tv";
            case 5:
                return "hardware/computer";
        }
    }

    readonly property bool isMobile: type == phone || type == phablet || type == tablet
}

单位和设备组件来自qml-material项目&#34; https://github.com/papyros/qml-material&#34;

添加此内容之后,您应该能够将每个像素语句包装到width: Units.dp(30)