Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. [SOLVED] What are properties for?

[SOLVED] What are properties for?

Scheduled Pinned Locked Moved General and Desktop
7 Posts 3 Posters 2.9k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • P Offline
    P Offline
    planarian
    wrote on last edited by
    #1

    Sorry if that seems like a dumb question, but none of the explanations I've read make it clear to me. I've looked at various code snippets that use them, but I'm not understanding when they're necessary.

    1 Reply Last reply
    0
    • M Offline
      M Offline
      mbnoimi
      wrote on last edited by
      #2

      Could you please provide us one of that snippets.

      1 Reply Last reply
      0
      • P Offline
        P Offline
        planarian
        wrote on last edited by
        #3

        I asked the question in such a general way because I was hoping for a general answer. But as an example, here's the icon editor from Blanchette/Summerfield 2nd ed. (p. 108):

        iconeditor.h
        @#ifndef ICONEDITOR_H
        #define ICONEDITOR_H

        #include <QColor>
        #include <QImage>
        #include <QWidget>

        class IconEditor : public QWidget
        {
        Q_OBJECT
        Q_PROPERTY(QColor penColor READ penColor WRITE setPenColor)
        Q_PROPERTY(QImage iconImage READ iconImage WRITE setIconImage)
        Q_PROPERTY(int zoomFactor READ zoomFactor WRITE setZoomFactor)

        public:
        IconEditor(QWidget *parent = 0);

        void setPenColor(const QColor &newColor);
        QColor penColor() const { return curColor; }
        void setZoomFactor(int newZoom);
        int zoomFactor() const { return zoom; }
        void setIconImage(const QImage &newImage);
        QImage iconImage() const { return image; }
        QSize sizeHint() const;
        

        protected:
        void mousePressEvent(QMouseEvent *event);
        void mouseMoveEvent(QMouseEvent *event);
        void paintEvent(QPaintEvent *event);

        private:
        void setImagePixel(const QPoint &pos, bool opaque);
        QRect pixelRect(int i, int j) const;

        QColor curColor;
        QImage image;
        int zoom;
        

        };

        #endif
        @

        iconeditor.cpp
        @#include <QtGui>

        #include "iconeditor.h"

        IconEditor::IconEditor(QWidget *parent)
        : QWidget(parent)
        {
        setAttribute(Qt::WA_StaticContents);
        setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);

        curColor = Qt::black;
        zoom = 8;
        
        image = QImage(16, 16, QImage::Format_ARGB32);
        image.fill(qRgba(0, 0, 0, 0));
        

        }

        void IconEditor::setPenColor(const QColor &newColor)
        {
        curColor = newColor;
        }

        void IconEditor::setZoomFactor(int newZoom)
        {
        if (newZoom < 1)
        newZoom = 1;

        if (newZoom != zoom) {
            zoom = newZoom;
            update();
            updateGeometry();
        }
        

        }

        void IconEditor::setIconImage(const QImage &newImage)
        {
        if (newImage != image) {
        image = newImage.convertToFormat(QImage::Format_ARGB32);
        update();
        updateGeometry();
        }
        }

        QSize IconEditor::sizeHint() const
        {
        QSize size = zoom * image.size();
        if (zoom >= 3)
        size += QSize(1, 1);
        return size;
        }

        void IconEditor::mousePressEvent(QMouseEvent *event)
        {
        if (event->button() == Qt::LeftButton) {
        setImagePixel(event->pos(), true);
        } else if (event->button() == Qt::RightButton) {
        setImagePixel(event->pos(), false);
        }
        }

        void IconEditor::mouseMoveEvent(QMouseEvent *event)
        {
        if (event->buttons() & Qt::LeftButton) {
        setImagePixel(event->pos(), true);
        } else if (event->buttons() & Qt::RightButton) {
        setImagePixel(event->pos(), false);
        }
        }

        void IconEditor::paintEvent(QPaintEvent *event)
        {
        QPainter painter(this);

        if (zoom >= 3) {
            painter.setPen(palette().foreground().color());
            for (int i = 0; i <= image.width(); ++i)
                painter.drawLine(zoom * i, 0,
                                 zoom * i, zoom * image.height());
            for (int j = 0; j <= image.height(); ++j)
                painter.drawLine(0, zoom * j,
                                 zoom * image.width(), zoom * j);
        }
        
        for (int i = 0; i < image.width(); ++i) {
            for (int j = 0; j < image.height(); ++j) {
                QRect rect = pixelRect(i, j);
                if (!event->region().intersect(rect).isEmpty()) {
                    QColor color = QColor::fromRgba(image.pixel(i, j));
                    if (color.alpha() < 255)
                        painter.fillRect(rect, Qt::white);
                    painter.fillRect(rect, color);
                }
            }
        }
        

        }

        void IconEditor::setImagePixel(const QPoint &pos, bool opaque)
        {
        int i = pos.x() / zoom;
        int j = pos.y() / zoom;

        if (image.rect().contains(i, j)) {
            if (opaque) {
                image.setPixel(i, j, penColor().rgba());
            } else {
                image.setPixel(i, j, qRgba(0, 0, 0, 0));
            }
        
            update(pixelRect(i, j));
        }
        

        }

        QRect IconEditor::pixelRect(int i, int j) const
        {
        if (zoom >= 3) {
        return QRect(zoom * i + 1, zoom * j + 1, zoom - 1, zoom - 1);
        } else {
        return QRect(zoom * i, zoom * j, zoom, zoom);
        }
        }
        @

        main.cpp
        @
        #include <QApplication>

        #include "iconeditor.h"

        int main(int argc, char *argv[])
        {
        QApplication app(argc, argv);
        IconEditor iconEditor;
        iconEditor.setWindowTitle(QObject::tr("Icon Editor"));
        iconEditor.setIconImage(QImage(":/images/mouse.png"));
        iconEditor.show();
        return app.exec();
        }
        @

        1 Reply Last reply
        0
        • A Offline
          A Offline
          andre
          wrote on last edited by
          #4

          A property, at least in Qt terms, is first and foremost a bundling of a series of methods on an object into a single semantic unit. Often, a getter, a setter and a signal are bundled under the flag of a single property. In your example, there are no signals attached to the properties, but there often are. So, instead of having separate methods to read and to write a value, a property bundles these conceptually.

          In Qt, properties also enable introspection. That is: you can query an object at runtime for what properties it supports, its name, its type, and you can read and often minipulate its value through a generic interface. That enables techniques like property editors: you can minipulate the values in an object at runtime, while at design time you did not know anyting about what kind of object you'd be manipulating. [[doc:QObject]] has the property() and setProperty() methods, that allow you to read and write any property in the object, or even to create new ones dynamically. If you want to see what properties an object has, [[doc:QMetaObject]] provides you with the means to query an object on what it offers in terms of properties, but also in terms of signals, slots and some other bits and pieces.

          1 Reply Last reply
          0
          • P Offline
            P Offline
            planarian
            wrote on last edited by
            #5

            Thanks, Andre, that explanation is very helpful. But when I look at the above example, I don't see many of these features in use: Only one of penColor's methods is called, on line 104 of iconeditor.cpp; iconImage has its bundled write method called directly on line 10 of main.cpp (apparently bypassing the property); zoomFactor isn't ever used! Am I missing something?

            1 Reply Last reply
            0
            • A Offline
              A Offline
              andre
              wrote on last edited by
              #6

              You're missing that it is only an example. API of classes is often designed in such a way that it would support more uses than just the example you're looking at. There is a pretty good chance the code for a sample was ripped out of something a bit bigger.

              1 Reply Last reply
              0
              • P Offline
                P Offline
                planarian
                wrote on last edited by
                #7

                Ok, so it sounds like this code doesn't need properties to function. It seems needlessly complicated for a textbook example, but oh well.

                1 Reply Last reply
                0

                • Login

                • Login or register to search.
                • First post
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • Users
                • Groups
                • Search
                • Get Qt Extensions
                • Unsolved