[Rinside-commits] r202 - pkg/inst/examples/qt
noreply at r-forge.r-project.org
noreply at r-forge.r-project.org
Sun Apr 3 22:44:30 CEST 2011
Author: edd
Date: 2011-04-03 22:44:29 +0200 (Sun, 03 Apr 2011)
New Revision: 202
Added:
pkg/inst/examples/qt/README
pkg/inst/examples/qt/main.cpp
pkg/inst/examples/qt/qtdensity.cpp
pkg/inst/examples/qt/qtdensity.h
pkg/inst/examples/qt/qtdensity.pro
Removed:
pkg/inst/examples/qt/qtdensity/
pkg/inst/examples/qt/qtdensitySVG/
Log:
moved qt example files back into top-level now that we have a merged SVG+PNG approach
Copied: pkg/inst/examples/qt/README (from rev 198, pkg/inst/examples/qt/qtdensitySVG/README)
===================================================================
--- pkg/inst/examples/qt/README (rev 0)
+++ pkg/inst/examples/qt/README 2011-04-03 20:44:29 UTC (rev 202)
@@ -0,0 +1,30 @@
+
+This directory provides a simple example of using RInside with the Qt
+toolkit---using a SVG renderer. Usage is standard Qt usage, do
+
+ qmake
+
+to generate a Makefile from the qmake source file ending in .pro, followed
+by
+
+ make
+
+which should generate the qtdensity binary. Doing
+
+ make clean
+
+tidies things up.
+
+To generate SVG output, this version depends on the cairoDevice package for R
+which you may need to install. According to its author Michael Lawrence,
+there are two small issues. The first is that the SVG produced by
+cairoDevice is a littler richer than the subset which Qt can show. We
+address this by filtering the file before viewing it. The other is an
+apparent error in the clipping which we cannot do anything about---Michael
+considers it a rendering issue.
+
+All the help by Michael in getting the svg variant to roll is gratefully
+acknowledged.
+
+
+
Copied: pkg/inst/examples/qt/main.cpp (from rev 198, pkg/inst/examples/qt/qtdensitySVG/main.cpp)
===================================================================
--- pkg/inst/examples/qt/main.cpp (rev 0)
+++ pkg/inst/examples/qt/main.cpp 2011-04-03 20:44:29 UTC (rev 202)
@@ -0,0 +1,20 @@
+// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8; -*-
+//
+// Qt usage example for RInside, inspired by the standard 'density
+// sliders' example for other GUI toolkits
+//
+// Copyright (C) 2011 Dirk Eddelbuettel and Romain Francois
+
+
+#include <QApplication>
+
+#include "qtdensity.h"
+
+int main(int argc, char *argv[])
+{
+ RInside R(argc, argv); // create an embedded R instance
+
+ QApplication app(argc, argv);
+ QtDensity qtdensity(R);
+ return app.exec();
+}
Copied: pkg/inst/examples/qt/qtdensity.cpp (from rev 200, pkg/inst/examples/qt/qtdensitySVG/qtdensity.cpp)
===================================================================
--- pkg/inst/examples/qt/qtdensity.cpp (rev 0)
+++ pkg/inst/examples/qt/qtdensity.cpp 2011-04-03 20:44:29 UTC (rev 202)
@@ -0,0 +1,183 @@
+// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8; -*-
+//
+// Qt usage example for RInside, inspired by the standard 'density
+// sliders' example for other GUI toolkits -- this time with SVG
+//
+// Copyright (C) 2011 Dirk Eddelbuettel and Romain Francois
+
+#include <QtGui>
+
+#include "qtdensity.h"
+
+QtDensity::QtDensity(RInside & R) : m_R(R)
+{
+ m_bw = 100; // initial bandwidth, will be scaled by 100 so 1.0
+ m_kernel = 0; // initial kernel: gaussian
+ m_cmd = "c(rnorm(100,0,1), rnorm(50,5,1))"; // simple mixture
+ m_R["bw"] = m_bw; // pass bandwidth to R, and have R compute a temp.file name
+ m_tempfile = QString::fromStdString(Rcpp::as<std::string>(m_R.parseEval("tfile <- tempfile()")));
+ m_svgfile = QString::fromStdString(Rcpp::as<std::string>(m_R.parseEval("sfile <- tempfile()")));
+ m_use_svg = m_R.parseEval("require(cairoDevice)");
+ if (!m_use_svg) {
+ std::cerr << "Consider installing the 'cairoDevice' package from CRAN to create SVG graphics." << std::endl;
+ }
+ setupDisplay();
+}
+
+void QtDensity::setupDisplay(void) {
+ QWidget *window = new QWidget;
+ window->setWindowTitle("Qt and RInside demo: density estimation");
+
+ QSpinBox *spinBox = new QSpinBox;
+ QSlider *slider = new QSlider(Qt::Horizontal);
+ spinBox->setRange(5, 200);
+ slider->setRange(5, 200);
+ QObject::connect(spinBox, SIGNAL(valueChanged(int)), slider, SLOT(setValue(int)));
+ QObject::connect(slider, SIGNAL(valueChanged(int)), spinBox, SLOT(setValue(int)));
+ spinBox->setValue(m_bw);
+ QObject::connect(spinBox, SIGNAL(valueChanged(int)), this, SLOT(getBandwidth(int)));
+
+ QLabel *cmdLabel = new QLabel("R command for random data creation");
+ QLineEdit *cmdEntry = new QLineEdit(m_cmd);
+ QObject::connect(cmdEntry, SIGNAL(textEdited(QString)), this, SLOT(getRandomDataCmd(QString)));
+ QObject::connect(cmdEntry, SIGNAL(editingFinished()), this, SLOT(runRandomDataCmd()));
+
+ QGroupBox *kernelRadioBox = new QGroupBox("Density Estimation kernel");
+ QRadioButton *radio1 = new QRadioButton("&Gaussian");
+ QRadioButton *radio2 = new QRadioButton("&Epanechnikov");
+ QRadioButton *radio3 = new QRadioButton("&Rectangular");
+ QRadioButton *radio4 = new QRadioButton("&Triangular");
+ QRadioButton *radio5 = new QRadioButton("&Cosine");
+ radio1->setChecked(true);
+ QVBoxLayout *vbox = new QVBoxLayout;
+ vbox->addWidget(radio1);
+ vbox->addWidget(radio2);
+ vbox->addWidget(radio3);
+ vbox->addWidget(radio4);
+ vbox->addWidget(radio5);
+ kernelRadioBox->setMinimumSize(260,140);
+ kernelRadioBox->setMaximumSize(260,140);
+ kernelRadioBox->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
+ kernelRadioBox->setLayout(vbox);
+
+ QButtonGroup *kernelGroup = new QButtonGroup;
+ kernelGroup->addButton(radio1, 0);
+ kernelGroup->addButton(radio2, 1);
+ kernelGroup->addButton(radio3, 2);
+ kernelGroup->addButton(radio4, 3);
+ kernelGroup->addButton(radio5, 4);
+ QObject::connect(kernelGroup, SIGNAL(buttonClicked(int)), this, SLOT(getKernel(int)));
+
+ if (m_use_svg) { // svg case
+ m_svg = new QSvgWidget();
+ } else { // png default
+ m_imageLabel = new QLabel;
+ m_imageLabel->setBackgroundRole(QPalette::Base);
+ m_imageLabel->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
+ m_imageLabel->setScaledContents(true);
+ m_image = new QImage(m_tempfile);
+ }
+ runRandomDataCmd(); // also calls plot()
+
+ QGroupBox *estimationBox = new QGroupBox("Density estimation bandwidth (scaled by 100)");
+ QHBoxLayout *spinners = new QHBoxLayout;
+ spinners->addWidget(spinBox);
+ spinners->addWidget(slider);
+ QVBoxLayout *topright = new QVBoxLayout;
+ topright->addLayout(spinners);
+ topright->addWidget(cmdLabel);
+ topright->addWidget(cmdEntry);
+ estimationBox->setMinimumSize(360,140);
+ estimationBox->setMaximumSize(360,140);
+ estimationBox->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
+ estimationBox->setLayout(topright);
+ QHBoxLayout *upperlayout = new QHBoxLayout;
+ upperlayout->addWidget(kernelRadioBox);
+ upperlayout->addWidget(estimationBox);
+
+ QHBoxLayout *lowerlayout = new QHBoxLayout;
+ if (m_use_svg) {
+ lowerlayout->addWidget(m_svg);
+ } else {
+ lowerlayout->addWidget(m_imageLabel);
+ }
+
+ QVBoxLayout *outer = new QVBoxLayout;
+ outer->addLayout(upperlayout);
+ outer->addLayout(lowerlayout);
+ window->setLayout(outer);
+ window->show();
+ if (!m_use_svg) {
+ window->resize(650, 750);
+ }
+}
+
+void QtDensity::plot(void) {
+ const char *kernelstrings[] = { "gaussian", "epanechnikov", "rectangular", "triangular", "cosine" };
+ m_R["bw"] = m_bw;
+ m_R["kernel"] = kernelstrings[m_kernel]; // that passes the string to R
+ std::string cmd0;
+ if (m_use_svg) { // select device based on whether cairoDevice is available or not
+ cmd0 = "Cairo(width=6,height=6,pointsize=10,surface='svg',filename=tfile); ";
+ } else {
+ cmd0 = "png(filename=tfile,width=600,height=600);";
+ }
+ std::string cmd1 = "plot(density(y, bw=bw/100, kernel=kernel), xlim=range(y)+c(-2,2), main=\"Kernel: ";
+ std::string cmd2 = "\"); points(y, rep(0, length(y)), pch=16, col=rgb(0,0,0,1/4)); dev.off()";
+ std::string cmd = cmd0 + cmd1 + kernelstrings[m_kernel] + cmd2; // stick the selected kernel in the middle
+ m_R.parseEvalQ(cmd);
+ if (m_use_svg) {
+ filterFile(); // we need to simplify the svg file for display by Qt
+ m_svg->load(m_svgfile);
+ } else {
+ m_image->load(m_tempfile);
+ m_imageLabel->setPixmap(QPixmap::fromImage(*m_image));
+ }
+}
+
+void QtDensity::getBandwidth(int bw) {
+ if (bw != m_bw) {
+ m_bw = bw;
+ plot();
+ }
+}
+
+void QtDensity::getKernel(int kernel) {
+ if (kernel != m_kernel) {
+ m_kernel = kernel;
+ plot();
+ }
+}
+
+void QtDensity::getRandomDataCmd(QString txt) {
+ m_cmd = txt;
+}
+
+void QtDensity::runRandomDataCmd(void) {
+ std::string cmd = "y <- " + m_cmd.toStdString();
+ m_R.parseEvalQ(cmd);
+ plot(); // after each random draw, update plot with estimate
+}
+
+void QtDensity::filterFile() {
+ // cairoDevice creates richer SVG than Qt can display
+ // but per Michaele Lawrence, a simple trick is to s/symbol/g/ which we do here
+
+ QFile infile(m_tempfile);
+ infile.open(QFile::ReadOnly);
+ QFile outfile(m_svgfile);
+ outfile.open(QFile::WriteOnly | QFile::Truncate);
+
+ QTextStream in(&infile);
+ QTextStream out(&outfile);
+ QRegExp rx1("<symbol");
+ QRegExp rx2("</symbol");
+ while (!in.atEnd()) {
+ QString line = in.readLine();
+ line.replace(rx1, "<g"); // so '<symbol' becomes '<g ...'
+ line.replace(rx2, "</g");// and '</symbol becomes '</g'
+ out << line << "\n";
+ }
+ infile.close();
+ outfile.close();
+}
Copied: pkg/inst/examples/qt/qtdensity.h (from rev 200, pkg/inst/examples/qt/qtdensitySVG/qtdensity.h)
===================================================================
--- pkg/inst/examples/qt/qtdensity.h (rev 0)
+++ pkg/inst/examples/qt/qtdensity.h 2011-04-03 20:44:29 UTC (rev 202)
@@ -0,0 +1,52 @@
+// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8; -*-
+//
+// Qt usage example for RInside, inspired by the standard 'density
+// sliders' example for other GUI toolkits
+//
+// Copyright (C) 2011 Dirk Eddelbuettel and Romain Francois
+
+#ifndef QTDENSITY_H
+#define QTDENSITY_H
+
+#include <RInside.h>
+
+#include <QMainWindow>
+#include <QHBoxLayout>
+#include <QSlider>
+#include <QSpinBox>
+#include <QLabel>
+#include <QTemporaryFile>
+#include <QSvgWidget>
+
+class QtDensity : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ QtDensity(RInside & R);
+
+private slots:
+ void getBandwidth(int bw);
+ void getKernel(int kernel);
+ void getRandomDataCmd(QString txt);
+ void runRandomDataCmd(void);
+
+private:
+ void setupDisplay(void); // standard GUI boilderplate of arranging things
+ void plot(void); // run a density plot in R and update the
+ void filterFile(void); // modify the richer SVG produced by R
+
+ QSvgWidget *m_svg; // the SVG device
+
+ QLabel *m_imageLabel; // image display in non-SVG case
+ QImage *m_image;
+
+ RInside & m_R; // reference to the R instance passed to constructor
+ QString m_tempfile; // name of file used by R for plots
+ QString m_svgfile; // another temp file, this time from Qt
+ int m_bw, m_kernel; // parameters used to estimate the density
+ QString m_cmd; // random draw command string
+ bool m_use_svg; // create SVG if cairoDevice can be loaded
+};
+
+#endif
Copied: pkg/inst/examples/qt/qtdensity.pro (from rev 201, pkg/inst/examples/qt/qtdensitySVG/qtdensity.pro)
===================================================================
--- pkg/inst/examples/qt/qtdensity.pro (rev 0)
+++ pkg/inst/examples/qt/qtdensity.pro 2011-04-03 20:44:29 UTC (rev 202)
@@ -0,0 +1,49 @@
+## -*- mode: Makefile; c-indent-level: 4; c-basic-offset: 4; tab-width: 8; -*-
+##
+## Qt usage example for RInside, inspired by the standard 'density
+## sliders' example for other GUI toolkits
+##
+## Copyright (C) 2011 Dirk Eddelbuettel and Romain Francois
+
+## build an app based on the one headers and two source files
+TEMPLATE = app
+HEADERS = qtdensity.h
+SOURCES = qtdensity.cpp main.cpp
+
+## beyond the default configuration, also use SVG graphics
+QT += svg
+
+## comment this out if you need a different version of R,
+## and set set R_HOME accordingly as an environment variable
+R_HOME = $$system(R RHOME)
+#message("R_HOME is" $$R_HOME)
+
+## include headers and libraries for R
+RCPPFLAGS = $$system($$R_HOME/bin/R CMD config --cppflags)
+RLDFLAGS = $$system($$R_HOME/bin/R CMD config --ldflags)
+RBLAS = $$system($$R_HOME/bin/R CMD config BLAS_LIBS)
+RLAPACK = $$system($$R_HOME/bin/R CMD config LAPACK_LIBS)
+
+## if you need to set an rpath to R itself, also uncomment
+#RRPATH = -Wl,-rpath,$$R_HOME/lib
+
+## include headers and libraries for Rcpp interface classes
+RCPPINCL = $$system($$R_HOME/bin/Rscript -e \'Rcpp:::CxxFlags\(\)\')
+RCPPLIBS = $$system($$R_HOME/bin/Rscript -e \'Rcpp:::LdFlags\(\)\')
+
+## for some reason when building with Qt we get this each time
+## /usr/local/lib/R/site-library/Rcpp/include/Rcpp/module/Module_generated_ctor_signature.h:25: warning: unused parameter ‘classname
+## so we turn unused parameter warnings off
+## no longer needed with Rcpp 0.9.3 or later
+#RCPPWARNING = -Wno-unused-parameter
+
+## include headers and libraries for RInside embedding classes
+RINSIDEINCL = $$system($$R_HOME/bin/Rscript -e \'RInside:::CxxFlags\(\)\')
+RINSIDELIBS = $$system($$R_HOME/bin/Rscript -e \'RInside:::LdFlags\(\)\')
+
+## compiler etc settings used in default make rules
+QMAKE_CXXFLAGS += $$RCPPWARNING $$RCPPFLAGS $$RCPPINCL $$RINSIDEINCL
+QMAKE_LFLAGS += $$RLDFLAGS $$RBLAS $$RLAPACK $$RCPPLIBS $$RINSIDELIBS
+
+## addition clean targets
+QMAKE_CLEAN += qtdensity Makefile
More information about the Rinside-commits
mailing list