Go back to Richel Bilderbeek's homepage.

Go back to Richel Bilderbeek's C++ page.

 

 

 

 

 

(C++) DrawGlobeQt

 

Qt Creator project to demonstrate DrawGlobe source code.

 

 

Operating system: Ubuntu 10.04 LTS Lucid Lynx

IDE: Qt Creator 2.0.0

Project type: GUI application

Compiler: G++ 4.4.1

Libraries used:

 

 

 

 

 

Qt project file

 

#-------------------------------------------------
#
# Project created by QtCreator 2010-08-13T11:59:16
#
#-------------------------------------------------

QT += core gui

TARGET = CppDrawGlobe
TEMPLATE = app


SOURCES += main.cpp\
dialog.cpp

HEADERS += dialog.h

FORMS += dialog.ui

RESOURCES += \
resources.qrc

 

 

 

 

 

dialog.cpp

 

#include <iostream>
#include <boost/lexical_cast.hpp>
#include <boost/numeric/conversion/cast.hpp>

#include <QDesktopWidget>

#include "dialog.h"
#include "ui_dialog.h"

Dialog::Dialog(QWidget *parent) :
    QDialog(parent, Qt::Window),
    ui(new Ui::Dialog)
{
  ui->setupUi(this);
  QObject::connect(ui->dial_r,SIGNAL(valueChanged(int)),this,SLOT(onAnyChange()));
  QObject::connect(ui->dial_g,SIGNAL(valueChanged(int)),this,SLOT(onAnyChange()));
  QObject::connect(ui->dial_b,SIGNAL(valueChanged(int)),this,SLOT(onAnyChange()));

  //Put the dialog in the screen center
  const QRect screen = QApplication::desktop()->screenGeometry();
  this->move( screen.center() - this->rect().center() );
}

Dialog::~Dialog()
{
  delete ui;
}

void Dialog::changeEvent(QEvent *e)
{
  QDialog::changeEvent(e);
  switch (e->type()) {
  case QEvent::LanguageChange:
    ui->retranslateUi(this);
    break;
  default:
    break;
  }
}

void Dialog::onAnyChange()
{

  ui->label_r->setText("Red: "
    + QString(boost::lexical_cast<std::string>(ui->dial_r->sliderPosition()).c_str()));
  ui->label_g->setText("Green: "
    + QString(boost::lexical_cast<std::string>(ui->dial_g->sliderPosition()).c_str()));
  ui->label_b->setText("Blue: "
    + QString(boost::lexical_cast<std::string>(ui->dial_b->sliderPosition()).c_str()));

  ui->label->setPixmap(
    DrawGlobe(
      ui->label->width(),
      ui->label->height(),
      ui->dial_r->sliderPosition(),
      ui->dial_g->sliderPosition(),
      ui->dial_b->sliderPosition()));
}

void Dialog::resizeEvent(QResizeEvent*)
{
  this->onAnyChange();
}

//From http://www.richelbilderbeek.nl/CppDrawGlobe.htm
QPixmap DrawGlobe(
  const int width,
  const int height,
  const unsigned char r,
  const unsigned char g,
  const unsigned char b)
{
  QPixmap pixmap(width,height);
  QImage image = pixmap.toImage();

  assert(image.bytesPerLine() / width == 4
    && "Assume there are 4 bytes per pixel");

  const double r_max = boost::numeric_cast<double>(r);
  const double g_max = boost::numeric_cast<double>(g);
  const double b_max = boost::numeric_cast<double>(b);
  const double midX = boost::numeric_cast<double>(width ) / 2.0;
  const double midY = boost::numeric_cast<double>(height) / 2.0;
  const double max_dist = std::min(midX,midY);

  for (int y=0; y!=height; ++y)
  {

    unsigned char * const line
      = static_cast<unsigned char *>(image.scanLine(y));
    const double y_d = boost::numeric_cast<double>(y);
    for (int x=0; x!=width; ++x)
    {
      const double x_d = boost::numeric_cast<double>(x);
      const double dist
        = std::sqrt(
            ((x_d - midX) * (x_d - midX))
          + ((y_d - midY) * (y_d - midY)) );
      if (dist <= max_dist)
      {
        const double rel_dist = dist / max_dist;
        const int r_here = rel_dist * r_max;
        const int g_here = rel_dist * g_max;
        const int b_here = rel_dist * b_max;
        assert( r_here >= 0);
        assert( r_here < 256);
        assert( g_here >= 0);
        assert( g_here < 256);
        assert( b_here >= 0);
        assert( b_here < 256);
        line[x*4+3] = 255; //Alpha value
        //New color values are 1 at least
        line[x*4+2] = (r_here == 0 ? 1 : r_here); //Red
        line[x*4+1] = (g_here == 0 ? 1 : g_here); //Green
        line[x*4+0] = (b_here == 0 ? 1 : b_here); //Blue
      }
      else
      {
        line[x*4+3] = 0; //Alpha value
        line[x*4+2] = 0; //Red
        line[x*4+1] = 0; //Green
        line[x*4+0] = 0; //Blue
      }
    }
  }
  pixmap = pixmap.fromImage(image);

  //Add transparency
  const QBitmap mask = pixmap.createMaskFromColor(QColor(0,0,0,0).rgb());
  pixmap.setMask(mask);

  return pixmap;
}

 

 

 

 

 

dialog.h

 

#ifndef DIALOG_H
#define DIALOG_H

#include <boost/shared_ptr.hpp>
#include <QDialog>

namespace Ui {
  class Dialog;
}

class Dialog : public QDialog
{
  Q_OBJECT

public:
  explicit Dialog(QWidget *parent = 0);
  ~Dialog();

protected:
  void changeEvent(QEvent *e);

private:
  Ui::Dialog *ui;
  void resizeEvent(QResizeEvent*);

private slots:
  void onAnyChange();
};

#endif // DIALOG_H

//From http://www.richelbilderbeek.nl/CppDrawGlobe.htm
QPixmap DrawGlobe(
  const int width,
  const int height,
  const unsigned char r,
  const unsigned char g,
  const unsigned char b);

 

 

 

 

 

main.cpp

 

#include <QtGui/QApplication>
#include "dialog.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Dialog w;
    w.show();

    return a.exec();
}

 

 

 

 

 

 

 

 

 

 

Go back to Richel Bilderbeek's C++ page.

Go back to Richel Bilderbeek's homepage.

 

Valid XHTML 1.0 Strict