2014-12-15 3 views
4

Как реализовать прямоугольник в QML с внутренней тенью?Внутренняя тень на прямоугольном прямоугольнике QML

Смотрите пример в ссылке ниже:

Create inner shadow in UIView

UPDATE:

Вот упрощенная версия того, что я пытаюсь сделать (который не показывает тени):

import QtQuick 2.0 
import QtGraphicalEffects 1.0 

Item { 
    width: 400 
    height: 400 

    Item { 
     anchors.fill: parent 

     Rectangle { 
     id: myRectangle 
     anchors.centerIn: parent 
     width: 200 
     height: 200 
     color: "grey" 
     } 
    } 

    InnerShadow { 
     anchors.fill: myRectangle 
     cached: true 
     visible: true 
     horizontalOffset: 0 
     verticalOffset: 0 
     radius: 25 
     samples: 16 
     color: "#b0000000" 
     smooth: true 
     source: myRectangle 
    } 
} 

Извините. Мое глупое ... Я ошибся, когда упростил код (элемент использовался для теста DropShadow, который работает). Вот как это должно было выглядеть так:

import QtQuick 2.0 
import QtGraphicalEffects 1.0 

Item { 
    width: 400 
    height: 400 

    Rectangle { 
     id: myRectangle 
     anchors.centerIn: parent 
     width: 200 
     height: 200 
     color: "grey" 
    } 

    InnerShadow { 
     anchors.fill: myRectangle 
     cached: true 
     visible: true 
     horizontalOffset: 0 
     verticalOffset: 0 
     radius: 25 
     samples: 16 
     color: "#b0000000" 
     smooth: true 
     source: myRectangle 
    } 
} 
+0

Якоря не работают с предметами, которые не являются родителями или братьями и сестрами, поэтому попробуйте переместить 'InnerShadow' в ваш' Item'. – cmannett85

+0

@ cmannett85 является правильным. Вы не видели никаких предупреждений/ошибок? В этом случае внутренний предмет становится спорным. – lpapp

+0

Перемещение внутри 'myRectangle' не является параметром для документации свойства' source' -> «Примечание. Не поддерживается включение эффекта, например, путем установки источника в родительский эффект.» – BaCaRoZzo

ответ

4

Я не знаю, почему, но это работает, если вы используете пункт выше элемента, который вы пытаетесь бросить тень внутри (в данном случае это просто случается корневой элемент, но он не должен быть):

import QtQuick 2.0 
import QtGraphicalEffects 1.0 

Item { 
    id: root 
    width: 300 
    height: 300 

    Rectangle { 
     id: myRectangle 
     anchors.centerIn: parent 
     width: 100 
     height: 100 
     color: "grey" 
    } 

    InnerShadow { 
     anchors.fill: root 
     cached: true 
     horizontalOffset: 0 
     verticalOffset: 0 
     radius: 16 
     samples: 32 
     color: "#b0000000" 
     smooth: true 
     source: root 
    } 
} 

inner shadow screenshot

Я получил идею от QTBUG-27213, когда я искал связанные с ошибками.

+0

Хороший. Вопрос в том, является ли это ошибкой или предполагаемым поведением? Учитывая исходный документ (я привел данный вопрос), он кажется первым, ИМО. – BaCaRoZzo

+1

Это определенно не кажется правильным; Я бы сказал, что стоит создать для него отчет об ошибке. – Mitch

+0

Создал ли вы отчет об ошибке? Вы можете связать его здесь для будущих ссылок? Спасибо :) – BaCaRoZzo

0

Здесь https://bugreports.qt.io/browse/QTBUG-56467 в первый комментарий является информативным ответом на эти вопросы,:

(с) Гуннар Sletta:

InnerShadow произведет оттенок в непрозрачных областях на основе прозрачных областей исходного объекта , Когда источник полностью непрозрачен (например, в случае этого прямоугольника, результат будет таким образом не затенением.

DropShadow имеет свойство transparentBorder, которое по умолчанию установлено в true, чтобы помочь пользователю получить ожидаемые результаты даже для полностью непрозрачный вход. InnerShadow не хватает этого.

на боковой ноте InnerShadow также использует «старый» гауссов код, который требует значительно больше образцов, чтобы получить право

Во всяком случае, так же получить внутреннюю тень на прямоугольнике должен быть нанесен один пиксель на прозрачные пиксели. Именно поэтому он иногда работает, чтобы предоставить родительскому объекту предполагаемого источника в качестве источника ef fect. (Обратите внимание, что это вообще не работает, и что на самом деле родитель не поддерживается как источник, так как многие GPU не сработают, когда вы это сделаете).

Следующий код дает ожидаемые результаты:

import QtQuick 2.4 
import QtGraphicalEffects 1.0 

Item 
{ 
    width: 320 
    height: 480 

    Item { 
     anchors.centerIn: parent 
     width: 100 
     height: 100 

     Rectangle { 
      anchors.fill: parent 
      anchors.margins: 1 
      color: "lightsteelblue" 
     } 

     layer.enabled: true 
     layer.effect: InnerShadow { 
      color: "black" 
      samples: 32 
      radius: 10 
      spread: 0.4 
     } 
    } 
} 

В качестве альтернативы, если вы хотите сохранить дополнительный элемент, и может жить чуть-чуть обман:

Rectangle { 
    anchors.centerIn: parent 
    width: 100 
    height: 100 
    color: "lightsteelblue" 
    border.color: Qt.rgba(0, 0, 0, 0.01) 
    border.width: 1 
    layer.enabled: true 
    layer.effect: InnerShadow { 
     color: "black" 
     samples: 20 
     radius: 8.5 
     spread: 0.2 
    } 
} 

(граница .color, не может быть «прозрачным», потому что это интерпретируется как нет границы)