Fundamentals of Coordinate Systems
Qt employs two distinct coordinate systems for graphics rendering:
Device Coordinate System
- Origin positioned at top-left corner (0,0)
- Measured in physical pixels
- X-axis extends rightward, Y-axis extends downward
Logical Coordinate System
- Abstract mathematical representation
- Unit measurement determined by application requirements
- Coordinate directions customizable based on specific use cases
Key Implementation Details
- QPainter operates exclusively in logical coordinates
- Logical coordinates undergo transformation to device coordinates
- Default configuraton aligns logical and device coordinate systems
Viewport and Window Concepts
These represent dual perspectives of the same rectanuglar region:
- Viewport: Physical rectangle in device coordinates
- Window: Corresponding rectangle in logical coordinates
- Bi-directional mapping exists between coordinate points
- Coordinate transformations enable mutual conversion
Coordinate Transformation Implementation
void CustomWidget::renderArea(QPaintEvent*)
{
QPainter renderer(this);
renderer.setViewport(40, 40, width()-80, height()-80);
renderer.setWindow(-8, 3, 16, -6);
renderer.fillRect(-8, 3, 16, -6, Qt::darkBlue);
}
Waveform Visualization Implementation
Header Definition
#ifndef RENDER_WIDGET_H
#define RENDER_WIDGET_H
#include <QWidget>
class RenderWidget : public QWidget
{
Q_OBJECT
protected:
void paintEvent(QPaintEvent*) override;
public:
explicit RenderWidget(QWidget* parent = nullptr);
};
#endif
Implementation Logic
#include "render_widget.h"
#include <QPainter>
#include <QtMath>
RenderWidget::RenderWidget(QWidget* parent) : QWidget(parent) {}
void RenderWidget::paintEvent(QPaintEvent*)
{
QPainter renderer(this);
QPen drawingPen(Qt::cyan);
drawingPen.setWidthF(0.02);
renderer.setPen(drawingPen);
renderer.setViewport(60, 60, width()-120, height()-120);
renderer.setWindow(-12, 3, 24, -6);
renderer.fillRect(-12, 3, 24, -6, QColor(20, 20, 20));
for(float vertical = -3, horizontal = -12; horizontal <= 12; vertical += 0.4, horizontal += 1.2)
{
renderer.drawLine(QPointF(-12, vertical), QPointF(12, vertical));
renderer.drawLine(QPointF(horizontal, 3), QPointF(horizontal, -3));
}
for(float xPos = -12; xPos < 12; xPos += 0.002)
{
float yPos = qSin(xPos);
renderer.drawPoint(QPointF(xPos, yPos));
}
}
Application Entry Point
#include "render_widget.h"
#include <QApplication>
int main(int argc, char* argv[])
{
QApplication app(argc, argv);
RenderWidget widget;
widget.show();
return app.exec();
}