Реклама
  • EVILEG
  • Ответ
  • 22 октября 2017 г. 12:05

Закрепление якорей в момент создания объекта через JS

Добрый день!
Якоря - это не те свойства, которые можно устанавливать сразу по инициализации, лучше их править после создания объекта, поскольку при одновременной установке они могут вести себя как попало. В этой статье сказано про этот момент. Поэтому лучше последовательная смена значений якорей, когда объект будет создан.


А что касается вашего вопроса, то я переписал бы код так.
main.qml
import QtQuick 2.6
import QtQuick.Window 2.2
import "object_creation.js" as Logic

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    Item {
        id: space
        anchors.top: parent.top
        anchors.left: parent.left
        anchors.right: parent.right
        anchors.bottom: parent.bottom

        Rectangle {
            id: bluerect
            color: "blue"
            height: 300
            width: 300
            anchors.verticalCenter: parent.verticalCenter
            anchors.left: parent.left
        }
    }

    Component.onCompleted: {
        Logic.create_object()
    }
}

Tester.qml
import QtQuick 2.5
import QtQuick.Controls 1.4

Rectangle
{
    color: "green"
    height: 300
    width: 300
    anchors.verticalCenter: parent.verticalCenter
    anchors.horizontalCenter: parent.horizontalCenter
}

object_creation.js
var id_donor = 0; //переменная для установки id
var component;
var sprite;

/*
    ---------------------------------------------------------
    Функция создаёт объект,
    описанный в tester.qml
    между left_neighbor и right_neighbor
    или между left_neighbor/right_neighbor и границей parent
    или между границами parent

    left_neighbor - string (qml-id объекта слева)
    right_neighbor - string (qml-id объекта справа)
    ---------------------------------------------------------
*/
function create_object(left_neighbor, right_neighbor) {
    var params = {}; //параметры создаваемого объекта
    params.id = id_donor; //устанавливаем id нового элемента

    component = Qt.createComponent("Tester.qml");
    sprite = component.createObject(space, params);
    if (left_neighbor !== undefined)
    {
        sprite.anchors.horizontalCenter = undefined;
        sprite.anchors.left = left_neighbor.right;
    }
    if (right_neighbor !== undefined)
    {
        sprite.anchors.horizontalCenter = undefined;
        sprite.anchors.right = right_neighbor.left;
    }

    id_donor++;
}
  • Kiops
  • Вопрос
  • 22 октября 2017 г. 2:15

Закрепление якорей в момент создания объекта через JS

Dynamic QML Object Creation from JavaScript, Динамическое создание компонент, Динамическое создание объектов, Acnhors, Позиционирование

Доброго времени суток.
Столкнулся с проблемой: при динамическом создании компоненты якори (anchors), передаваемые как параметры при создании, не закрепляются. Прошу подсказать, что я делаю неправильно. Далее подробнее и с кодом.


Задача состоит в создании объектов внутри объекта Item в горизонтальный ряд, с возможностью добавления элементов в любом конце ряда.
Желаемый результат работы программы: при вызове create_object(null, null) создаётся зелёный квадрат по центру Item с id = space.
Фактический результат: зелёный квадрат создаётся по вертикальному центру, но у левого края объекта Item с id = space.
Иллюстрация в приложении

N.b. Код является лишь наброском и может содержать ошибки, не связанные с описанной проблемой.

object_creation_test.js:
var id_donor = 0; //переменная для установки id
var component;
var sprite;

/*
    ---------------------------------------------------------
    Функция создаёт объект,
    описанный в tester.qml
    между left_neighbor и right_neighbor
    или между left_neighbor/right_neighbor и границей parent
    или между границами parent

    left_neighbor - string (qml-id объекта слева)
    right_neighbor - string (qml-id объекта справа)
    ---------------------------------------------------------
*/
function create_object(left_neighbor, right_neighbor) {
    var params = {}; //параметры создаваемого объекта

    /* Если слева/справа имеется сосед, то прибиваем к нему якорь, в противном случае прибиваем якорь к родителю */
    params["anchors.left"] = (left_neighbor !== null) ? left_neighbor + ".right" : "parent.left";
    params["anchors.right"] = (right_neighbor !== null) ? right_neighbor + ".left" : "parent.right";

    params.id = id_donor; //устанавливаем id нового элемента

    component = Qt.createComponent("tester.qml");
    sprite = component.createObject(space, params);
    id_donor++;
}
tester.qml:
import QtQuick 2.5
import QtQuick.Controls 1.4

Rectangle
{
    color: "green"
    height: 300
    width: 300
    anchors.verticalCenter: parent.verticalCenter
}
Объект, в котором создаются объекты tester:
            Item {
                id: space
                anchors.top: row.bottom
                anchors.left: parent.left
                anchors.right: parent.right
                anchors.bottom: parent.bottom
            }

QFile::copy() возвращает false

Каталог foto есть.

Сделал следующую проверку:
if (!QFile(path1).exists()) {
          qWarning("The source file does not exist");
          return 1;
      }
И получил
The source file does not exist
Путь к копируемому файлу беру отсюда:
Image {
                        id: image_foto
                        height: image_shema.height
                        width: parent.width
                        anchors.horizontalCenter: parent.horizontalCenter
                        anchors.bottom: parent.bottom
                        anchors.bottomMargin: 5
                        fillMode: Image.PreserveAspectFit
                        source: "Images/add_foto.png"
                        FileDialog {
                                id: fileDialogLoad_foto
                                objectName: "foto"
                                property string path: ""
                                folder: "."
                                title: "Choose a file to open"
                                selectMultiple: false
                                nameFilters: [ "Image files (*.png *.jpg)", "All files (*)" ]
                                onAccepted: { console.log("Accepted: " + fileUrl)
                                    fileDialogLoad_foto.path = fileUrl
                                qmlSignal()
                                }
                            }
                        MouseArea {
                            anchors.fill: parent
                            onClicked: {
                                fileDialogLoad_foto.open()                                
                            }
                        }
                    }
  • EVILEG
  • Комментарий
  • 18 октября 2017 г. 14:45

QML - Урок 031. Отключаем системное обрамление окна в QML и пишем код для обработки перемещения и ресайза окна

Задать свои property в окне и проверять их в методах изменения размера для topArea, bottomArea, rightArea, leftArea.

В обработчиках onMouseYChanged, onMouseXChanged.
Из-за отключения обрамления не отслеживаются минимальные рамеры, поэтому нужно следить за этим самостоятельно
  • EVILEG
  • Ответ
  • 15 октября 2017 г. 16:58

Описание класса С++ в QtCreator

День добрый!


Заголовочник будет выглядеть следующим способом. Назовём его button.h
button.h
class Button : public QGraphicsWidget
{
    Q_OBJECT
public:
    Button(const QPixmap &pixmap, QGraphicsItem *parent = 0);

    QRectF boundingRect() const override;
    QPainterPath shape() const override;
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *) override;

signals:
    void pressed();

protected:
    void mousePressEvent(QGraphicsSceneMouseEvent *) override;
    void mouseReleaseEvent(QGraphicsSceneMouseEvent *) override;

private:
    QPixmap _pix;
};
А реализация должна выглядеть так:
button.cpp
Button(const QPixmap &pixmap, QGraphicsItem *parent = 0)
    : QGraphicsWidget(parent), _pix(pixmap)
{
    setAcceptHoverEvents(true);
    setCacheMode(DeviceCoordinateCache);
}

QRectF boundingRect() const 
{
    return QRectF(-65, -65, 130, 130);
}

QPainterPath shape() const 
{
    QPainterPath path;
    path.addEllipse(boundingRect());
    return path;
}

void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *) 
{
    bool down = option->state & QStyle::State_Sunken;
    QRectF r = boundingRect();
    QLinearGradient grad(r.topLeft(), r.bottomRight());
    grad.setColorAt(down ? 1 : 0, option->state & QStyle::State_MouseOver ? Qt::white : Qt::lightGray);
    grad.setColorAt(down ? 0 : 1, Qt::darkGray);
    painter->setPen(Qt::darkGray);
    QLinearGradient grad2(r.topLeft(), r.bottomRight());
    painter->setBrush(grad);
    painter->drawEllipse(r);
    grad.setColorAt(down ? 1 : 0, Qt::darkGray);
    grad.setColorAt(down ? 0 : 1, Qt::lightGray);
    painter->setPen(Qt::NoPen);
    painter->setBrush(grad2);
    if (down)
        painter->translate(2, 2);
    painter->drawEllipse(r.adjusted(5, 5, -5, -5));
    painter->drawPixmap(-_pix.width()/2, -_pix.height()/2, _pix);
}

void mousePressEvent(QGraphicsSceneMouseEvent *) 
{
    emit pressed();
    update();
}

void mouseReleaseEvent(QGraphicsSceneMouseEvent *) 
{
    update();
}
Q_DECL_OVERRIDE - это Qt-шный макрос, который просто подставляет override, что означает, что это переопределённая виртуальная функция, можете спокойно заменить Q_DECL_OVERRIDE на override. В Qt грешат тем, что делают свои макросы на всё. В крупных проектах эти лишние макросы очень сильно скажутся на скорости компиляции, поэтому следует использовать стандартные средства C++ при разработке проекта.

И ещё там понадобится подключить нужные заголовочные файлы. Они у вас должны быть перечислены в файле main.cpp, ну там всякие #include <QGraphicsWidget> , которые относятся к этому классу.
  • Mark
  • Вопрос
  • 15 октября 2017 г. 16:45

Описание класса С++ в QtCreator

Qt, C++, классы

Здравствуйте!

Есть реализация класса в main.cpp(создается и используется там же)
class Button : public QGraphicsWidget
{
    Q_OBJECT
public:
    Button(const QPixmap &pixmap, QGraphicsItem *parent = 0)
        : QGraphicsWidget(parent), _pix(pixmap)
    {
        setAcceptHoverEvents(true);
        setCacheMode(DeviceCoordinateCache);
    }

    QRectF boundingRect() const Q_DECL_OVERRIDE
    {
        return QRectF(-65, -65, 130, 130);
    }

    QPainterPath shape() const Q_DECL_OVERRIDE
    {
        QPainterPath path;
        path.addEllipse(boundingRect());
        return path;
    }

    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *) Q_DECL_OVERRIDE
    {
        bool down = option->state & QStyle::State_Sunken;
        QRectF r = boundingRect();
        QLinearGradient grad(r.topLeft(), r.bottomRight());
        grad.setColorAt(down ? 1 : 0, option->state & QStyle::State_MouseOver ? Qt::white : Qt::lightGray);
        grad.setColorAt(down ? 0 : 1, Qt::darkGray);
        painter->setPen(Qt::darkGray);
        QLinearGradient grad2(r.topLeft(), r.bottomRight());
        painter->setBrush(grad);
        painter->drawEllipse(r);
        grad.setColorAt(down ? 1 : 0, Qt::darkGray);
        grad.setColorAt(down ? 0 : 1, Qt::lightGray);
        painter->setPen(Qt::NoPen);
        painter->setBrush(grad2);
        if (down)
            painter->translate(2, 2);
        painter->drawEllipse(r.adjusted(5, 5, -5, -5));
        painter->drawPixmap(-_pix.width()/2, -_pix.height()/2, _pix);
    }

signals:
    void pressed();

protected:
    void mousePressEvent(QGraphicsSceneMouseEvent *) Q_DECL_OVERRIDE
    {
        emit pressed();
        update();
    }

    void mouseReleaseEvent(QGraphicsSceneMouseEvent *) Q_DECL_OVERRIDE
    {
        update();
    }

private:
    QPixmap _pix;
};
Как разделить  данный на класс на заголовочный файл с его объявлением и на *.cpp с его реализацией в QtCreator?
И что означает Q_DECL_OVERRIDE??
  • EVILEG
  • Ответ
  • 14 октября 2017 г. 18:29

Рисуем линию QGraphicsItem за мышью

Я поправил немного Ваш код.

Смотрите какие здесб будут моменты:
Не нужно передавать mouseEvent в метод mouseMoveEvent(), лучше сделать отдельный методв для установки конечной точки линии и вызывать метод перерисовки.
void MyLine::setEndPoint(QPointF endPoint)
{
    p2 = endPoint;
    update();
}
Также, неправильная реализация методы boundingRect(), там нужно следить за правильностью использования точек topLeft и rightBottom, поскольку точки p1 и p2 могут им несоответсвуовать в линии.
QRectF MyLine::boundingRect() const
{
    QPointF topLeft = QPointF(p1.x() < p2.x() ? p1.x() : p2.x(),
                              p1.y() < p2.y() ? p1.y() : p2.y());
    QPointF rightBootom = QPointF(p1.x() > p2.x() ? p1.x() : p2.x(),
                                  p1.y() > p2.y() ? p1.y() : p2.y());
    return QRectF(topLeft, rightBootom);
}
Метода mouse event`ов в линии не потребуются в данном случае, я их удалил.
Также несколько поправил методы перемещения мыши в графической сцене.
void MyScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent)
{
    if ((mouseEvent->button() == Qt::LeftButton)&&(isDrawLine))
    {
        isDrawLine = false;
        addMyLine(mouseEvent->scenePos());
    }
}

void MyScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent)
{
    line->setEndPoint(mouseEvent->scenePos());
    update();
}
Весь проект во вложении.

Добавление строки в Combobox

Здравствуйте! Подскажите, как добавить пустую строку в Combobox?

ComboBox {
        id: combo_ceh
        property string id: ""
        currentIndex: -1
        anchors.top: tf_kks.bottom
        anchors.topMargin: 5
        anchors.left: text_ceh.right
        anchors.leftMargin: 5
        Material.accent: Material.LightBlue
        model: model_ceh
        textRole: 'Cehname'
        onCurrentTextChanged: {
            if(currentIndex==-1){
                combo_ceh.id = ""                
            } else {
            combo_ceh.id = model_ceh.getId(currentIndex)            
            }
        }
    }
Реклама
  • BlinCT
  • 22 октября 2017 г. 12:46

C++ - Тест 003. Условия и циклы

  • Результат 64 баллов
  • Очки рейтинга -1
  • Kiops
  • 22 октября 2017 г. 3:56

C++ - Тест 001. Первая программа и типы данных

  • Результат 86 баллов
  • Очки рейтинга 6
  • Kiops
  • 22 октября 2017 г. 2:41

Qt - Тест 001. Сигналы и слоты

  • Результат 100 баллов
  • Очки рейтинга 10
Последние комментарии
  • EVILEG
  • 21 октября 2017 г. 3:06

Qt/C++ - Урок 031. QCustomPlot - строим график по времени

Добавил архив с проектом

  • EVILEG
  • 20 октября 2017 г. 20:06

Qt/C++ - Урок 031. QCustomPlot - строим график по времени

После работы поищу, должен где-то быть на винте.

  • Миша
  • 20 октября 2017 г. 20:04

Qt/C++ - Урок 031. QCustomPlot - строим график по времени

не могли бы вы выложить архив с рабочей версией скрипта?

  • EVILEG
  • 20 октября 2017 г. 20:03

Qt/C++ - Урок 030. QCustomPlot - быстрый старт в работе с графиками

Использование дизайнера в Qt Creator и использование ui файлов является распространённой практикой в Qt фреймворке. Написать отдельную статью про то, что это такое? - может быть. Опи...

  • Миша
  • 20 октября 2017 г. 19:43

Qt/C++ - Урок 030. QCustomPlot - быстрый старт в работе с графиками

Но почему вы это не описали? Не могли бы вы описать.

Сейчас обсуждают на форуме
  • EVILEG
  • 22 октября 2017 г. 12:05

Закрепление якорей в момент создания объекта через JS

Добрый день! Якоря - это не те свойства, которые можно устанавливать сразу по инициализации, лучше их править после создания объекта, поскольку при одновременной установке они могут в...

  • EVILEG
  • 21 октября 2017 г. 23:33

Создание истории редактирования постов на сайте

Ясно. Тогда я лучше не буду тратить время на его проверку. Тем более, что я использую гугловский prettyprint для подсветки кода. Спасибо за информацию.

QFile::copy() возвращает false

Получилось! Спасибо огромное! path1 = "C:/Users/555/Pictures/00GAF13AP001-002.jpg"true

  • cordsac
  • 19 октября 2017 г. 15:49

How can I select the QGraphicView Item and change the properties

Ok I'll check it sir,If you can please do article(tutorial) about this,Its really useful.Thank you if you can give me some sample code when you free.thanks again

  • cordsac
  • 17 октября 2017 г. 19:28

How can I open SVG file through QT

Okay,Thank you sir :)