I have a Fl_Choice with few options, for example:
Fl_Choice* o = new Fl_Choice(70, 100, 240, 25, "Some Options:");
o->add("Blue");
o->add("Black");
o->add("Orange");
o->add("Purple");
I did like to set a custom color for the background of each item while leaving the foreground color to white.
How do I set a custom background per item?
NOTE: I am using v90, not sure what tag I should use for that one or if vs2008 is sufficient, kindly remove this note if its sufficient as is or drop me a comment with what other tag I should add.
Not so easy to set the background colour but you can set the foreground colour
Fl_Menu_Item choices[] =
{
// ,-- The colour
{"red",0,(Fl_Callback*)0, (void*) 0, 0, 0, 0, 0, 0xFF000000},
{"blue",0,(Fl_Callback*)0, (void*) 0, 0, 0, 0, 0, 0x0000FF00},
{"green",0,(Fl_Callback*)0, (void*) 0, 0, 0, 0, 0, 0x00FF0000},
{"yellow",0,(Fl_Callback*)0, (void*) 0, 0, 0, 0, 0, 0xFFFF0000},
{0}
};
...
Fl_Choice *c = new Fl_Choice(50,250,200,25);
c->menu(choices);
Alternatively, you can derive from Fl_Choice if you don't want so many zeros
class ColourChoice: public Fl_Choice
{
public:
ColourChoice(int x, int y, int w, int h, const char* l = 0)
: Fl_Choice(x, y, w, h, l)
{
}
void add(const char* text, Fl_Color color)
{
Fl_Choice::add(text);
Fl_Menu_Item* item = const_cast<Fl_Menu_Item*>(find_item(text));
item->labelcolor(color);
}
};
...
ColourChoice* c = new ColourChoice(...);
c->add("purple", (Fl_Color)0xFF00FF00);
Related
I want to get the object of the class which is constructed in main() function and use this object in another class.
This is the class I want to take the object of it:
typedef enum {
DOWN = 1,
LEFT = 2,
UP = 3,
RIGHT = 4
} tWaypointDir;
class Waypoint
{
sf::Texture texture;
sf::Sprite sprite;
public:
float x, y;
int dir;
int next1, next2, next3;
Waypoint(tWaypointDir dir, tRoadTileType type, int row, int col, int idx, int next1, int next2, int next3); // Constructor for the class.
// idx: internal index of the waypoints, next1, 2, 3: next waypoints of the current one.
// if there is only next1, next2 and next3 are -1.
int getNext(); //Get next waypoint randomly
void getPosition(float &x, float &y, float &dir) const { x = this->x; y = this->y; dir = this->dir; }
void setPosition(float x, float y, float dir) { this->x = x; this->y = y; this->dir = dir; }
void draw(sf::RenderWindow *window) {window->draw(sprite);}
};
The object I created in the main() function is:
Waypoint waypoints[] = { //CTL: Road at top-left, HOR: horizontal, etc..
{UP, CTL, 0, 0, 0, 1, -1, -1}, {RIGHT, CTL, 0, 0, 1, 0, -1, -1},
{RIGHT, HOR, 0, 1, 0, 3, -1, -1}, {RIGHT, HOR, 0, 1, 1, 2, -1, -1},
{RIGHT, TTOP, 0, 2, 0, 5, 6, -1}, {DOWN, TTOP, 0, 2, 1, 4, 6, -1},
{RIGHT, TTOP, 0, 2, 2, 4, 5, -1}, {RIGHT, HOR, 0, 3, 0, 8, -1, -1}
};
Now, in the class Car, I want to use the waypoints[] object because I move the car in the direction of waypoints. I have a move() function in this class and I used this object in that part. We are not allowed to do the movement in main() function. Hence, I have to implement this in the class.
I tried the Singleton design pattern on the Waypoint class but it gives me errors on the constructor part. How can I implement this on the Car class?
You can pass pointer or reference on Waypoint class as argument in Car class constructor or method. Car class could store this reference or pointer as member. Then you can access this object from Car class
I've been trying to use QGraphicsItemGroup to get the bounding rectangle of a group of QGraphicsItem*s. It appears to me that the bounding rectangle is correctly determined when I insert all of the items into the group; but if I then move items in the group, the bounding rectangle does not update to contain the moved items as I expect. I cannot find indication in the Documentation as to whether what I'm seeing is correct behavior or not; my guess is that I'm either misunderstanding how the QGraphicsItemGroup works or misusing it
An example that I've been using to test:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QTransform>
#include <QGraphicsEllipseItem>
#include <QDebug>
#include <QTimer>
#include <cmath>
const double pi = 3.14;
QTransform rotation(double degrees)
{
double a = pi/180 * degrees;
double sina = sin(a);
double cosa = cos(a);
return QTransform(cosa, sina, -sina, cosa, 0, 0);
}
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
scene = new QGraphicsScene(this);
ui->graphicsView->setScene(scene);
ui->graphicsView->show();
//Shouldn't execute until after window.show() and application.exec()
//are called
QTimer::singleShot(1, this, &MainWindow::build);
}
void MainWindow::build()
{
QGraphicsEllipseItem* el1 = scene->addEllipse(-5, -5, 10, 10);
scene->addLine(0, 0, 0, 10)->setParentItem(el1);
QGraphicsEllipseItem* el2 = scene->addEllipse(-5, -5, 10, 10);
scene->addLine(0, 0, 0, 10)->setParentItem(el2);
QGraphicsEllipseItem* el3 = scene->addEllipse(-5, -5, 10, 10);
scene->addLine(0, 0, 0, 10)->setParentItem(el3);
QGraphicsEllipseItem* el4 = scene->addEllipse(-5, -5, 10, 10);
scene->addLine(0, 0, 0, 10)->setParentItem(el4);
QGraphicsItemGroup* group = new QGraphicsItemGroup;
group->addToGroup(el1);
group->addToGroup(el2);
group->addToGroup(el3);
group->addToGroup(el4);
scene->addItem(group);
scene->addRect(group->boundingRect());
QTransform translate2(1, 0, 0, 1, 10, 10);
QTransform t2 = /*rotation(45) **/ translate2;
el2->setTransform(t2);
QTransform translate3(1, 0, 0, 1, 20, 20);
QTransform t3 = /*rotation(-45) **/ translate3 * t2;
el3->setTransform(t3);
QTransform translate4(1, 0, 0, 1, 20, -20);
QTransform t4 = translate4 * t3;
el4->setTransform(t4);
qDebug() << t4.dx() << t4.dy() << atan2(t4.m12(), t4.m22())*180/pi;
QTransform t4i = t4.inverted();
qDebug() << t4i.dx() << t4i.dy() << atan2(t4i.m12(), t4i.m22())*180/pi;
scene->addRect(group->boundingRect());
}
MainWindow::~MainWindow()
{
delete ui;
}
The final scene displayed looks like this
Actual outcome
But, I was expecting something like this, with a small box from the first boundingRect, and a larger one for the second
Expected outcome
Am I misunderstanding how the QGraphicsItemGroup works, or am I using it incorrectly?
Qt Version: 5.10
OS: Ubuntu 16.04
Compiler GCC 5.4
The boundingrect is only updated at additem. Therefore the method childrenBoundingRect() must be used instead of boundingRect().
In a separate subclass of QGraphicsItemGroup say MyQGraphicsItemGroup we can overload the method virtual QRectF boundingRect() const override so that childrenBoundingRect() is called.
QRectF MyQGraphicsItemGroup::boundingRect() const
{
// must be overloaded, otherwise the boundingrect will only be actualized on
// additem is actualized. This leads to the fact that the boundingrect
// will not close around the word items after e.g., moving them.
return childrenBoundingRect();
}
The QGraphicsItemGroup documentation doesn't seem to mention this, but it only recalculates the boundingRect for a QGraphicsItemGroup after the view and QGraphicsScene is shown.
Adding the items afterwards
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QGraphicsScene scene;
QGraphicsView mainView(&scene);
scene.setSceneRect(0, 0, 800, 800);
QGraphicsEllipseItem* el1 = scene.addEllipse(-5, -5, 10, 10);
scene.addLine(0, 0, 0, 10)->setParentItem(el1);
QGraphicsEllipseItem* el2 = scene.addEllipse(-5, -5, 10, 10);
scene.addLine(0, 0, 0, 10)->setParentItem(el2);
QGraphicsEllipseItem* el3 = scene.addEllipse(-5, -5, 10, 10);
scene.addLine(0, 0, 0, 10)->setParentItem(el3);
QGraphicsEllipseItem* el4 = scene.addEllipse(-5, -5, 10, 10);
scene.addLine(0, 0, 0, 10)->setParentItem(el4);
QGraphicsItemGroup* group = new QGraphicsItemGroup;
scene.addItem(group);
QTransform translate2(1, 0, 0, 1, 10, 10);
QTransform t2 = /*rotation(45) **/ translate2;
el2->setTransform(t2);
QTransform translate3(1, 0, 0, 1, 20, 20);
QTransform t3 = /*rotation(-45) **/ translate3 * t2;
el3->setTransform(t3);
QTransform translate4(1, 0, 0, 1, 20, -20);
QTransform t4 = translate4 * t3;
el4->setTransform(t4);
mainView.show();
group->addToGroup(el1);
group->addToGroup(el2);
group->addToGroup(el3);
group->addToGroup(el4);
scene.addRect(group->boundingRect());
qDebug() << group->sceneBoundingRect() << endl << group->boundingRect();
scene.addRect(group->sceneBoundingRect());
return a.exec();
}
Results in the bounding rect of all members of the group
I am trying to get a subimage of a CImg. As I understand the method get_crop() does what I need, but the subimages that I get do not contain the pixel values I expected them to have.
unsigned char* StringTextureGenerator::GetTexture(int &width, int &height)
{
cil::CImg<unsigned char>* tmp = new cil::CImg<unsigned char>(512, 512, 1, 4);
*tmp = _alphabet.get_crop(0, 0, 0, 0, 511, 511, 0, 3);
width = tmp->width();
height = tmp->height();
return tmp->data();
}
The _alphabet CImg is 512x512x1x4 and contains an rgba image. For a test I am trying to get the whole the image x = 0 - 511, y = 0 - 511.
The result is this:
This is the expected outcome. I got the whole image as I loaded it from the file.
But when I try to get a sub-image, strange things do happen.
unsigned char* StringTextureGenerator::GetTexture(int &width, int &height)
{
cil::CImg<unsigned char>* tmp = new cil::CImg<unsigned char>(256, 256, 1, 4);
*tmp = _alphabet.get_crop(0, 0, 0, 0, 255, 255, 0, 3);
width = tmp->width();
height = tmp->height();
return tmp->data();
}
Here I am getting the pixels x = 0 - 255, y = 0 - 255, which I expect to be the top left quarter of the picture.
The result is this:
As you can see I get the top left quarter of every 128x128 block. Which is not what I wanted.
Not sure what is going on with your code, but this works fine on my machine. I am using CImg v169. I use this as a test image:
And run this code:
#include <iostream>
#include "CImg.h"
using namespace cimg_library;
int main()
{
CImg<unsigned char> alphabet = CImg<unsigned char>("alphabet.png");
CImg<unsigned char> tmp = CImg<unsigned char>(512, 512, 1, 4);
//tmp = alphabet.get_crop(0, 0, 0, 0, 511, 511, 0, 3);
tmp = alphabet.get_crop(0, 0, 0, 0, 255, 255, 0, 3);
tmp.save_png("result.png");
}
And get this, which looks correct to me:
I am compiling with options:
-Dcimg_use_png -lpng -lz
I've studied Opencv's setMouseCallback function.
I understand there are several events, list below:
CV_EVENT_MOUSEMOVE 0,
CV_EVENT_LBUTTONDOWN 1,
CV_EVENT_RBUTTONDOWN 2,
CV_EVENT_MBUTTONDOWN 3,
CV_EVENT_LBUTTONUP 4,
CV_EVENT_RBUTTONUP 5,
CV_EVENT_MBUTTONUP 6,
CV_EVENT_LBUTTONDBLCLK 7,
CV_EVENT_RBUTTONDBLCLK 8,
CV_EVENT_MBUTTONDBLCLK 9,
CV_EVENT_FLAG_LBUTTON 1,
CV_EVENT_FLAG_RBUTTON 2,
CV_EVENT_FLAG_MBUTTON 4,
CV_EVENT_FLAG_CTRLKEY 8,
CV_EVENT_FLAG_SHIFTKEY 16,
CV_EVENT_FLAG_ALTKEY 32,
and with the coordinates I get from these events, I can draw, for example: straight line, circle, ellipse...etc.
But instead of straight line, I want to draw random line, just like the "pencil" or "brush" function in Microsoft Paint.
The CV_EVENT_MOUSEMOVE does return all the coordinates as my mouse move through the image, but I don't know how to combine it with CV_EVENT_LBUTTONDOWN to represent "Start drawing line" and CV_EVENT_LBUTTONUP to represent "Finish drawing line"?
Does anyone know how to achieve my requirement with setMouseCallback?
I figured it out myself,
bool trigger;
Mat img;
void onMouse(int event, int x, int y, int flag, int param)
{
if(event == CV_EVENT_LBUTTONDOWN)
{
img = Mat::zeros(320, 240, CV_8UC3);
trigger = true;
}
if(event == CV_EVENT_LBUTTONUP)
{
trigger = false;
}
if(event == CV_EVENT_MOUSEMOVE)
{
if(trigger == true)
{
line(img, cvPoint(x, y), cvPoint(x, y), Scalar(0, 0, 255), 3, CV_AA, 0);
imshow("Drawing", img);
}
}
}
int main(int argc, char *argv[])
{
.
.
.
cvsetMouseCallback("Origin img", onMouse, NULL);
.
.
.
}
I'd like to write a QDeclarativeItem FadeEdges that I instantiate from QML, such as in this example:
FadeEdges {
Text {
id: sometext
text: "some text"
}
}
After sometext repaints, I'd like to reduce the alphas (from fully opaque to transparent) of the pixels it painted at its edges. So its rendered edges will appear faded. My question is what mechanisms, if any, are available to make this change in child alpha values.
I've tried to install event filters and setting setFiltersChildEvents(). No PaintEvents seem to be sent.
It is not an exact answer to my own question but I suppose it will do for starters. Only the QGraphicsEffect::draw member function needs to be overridden (margins_ is a QMargins member variable):
void FadeEdgesEffect::draw(QPainter* painter)
{
QLinearGradient lg;
lg.setColorAt(qreal(0), QColor(0, 0, 0, 0));
lg.setColorAt(qreal(1), QColor(0, 0, 0, 255));
qreal const width(boundingRect().width());
qreal const height(boundingRect().height());
QPoint offset;
QPixmap pixmap(sourcePixmap(Qt::LogicalCoordinates, &offset));
{
QPainter p(&pixmap);
p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
if (margins_.left())
{
lg.setStart(qreal(0), qreal(0));
lg.setFinalStop(margins_.left(), qreal(0));
p.fillRect(QRectF(0, 0, margins_.left(), height), lg);
}
// else do nothing
if (margins_.right())
{
lg.setStart(qreal(width), qreal(0));
lg.setFinalStop(width - margins_.right(), qreal(0));
p.fillRect(QRectF(width - margins_.right(),
0, margins_.right(), height), lg);
}
// else do nothing
if (margins_.bottom())
{
lg.setStart(qreal(0), height);
lg.setFinalStop(qreal(0), height - margins_.top());
p.fillRect(QRectF(0, height - margins_.bottom(),
width, margins_.bottom()), lg);
}
// else do nothing
if (margins_.top())
{
lg.setStart(qreal(0), qreal(0));
lg.setFinalStop(0, margins_.top());
p.fillRect(QRectF(0, 0, width, margins_.top()), lg);
}
// else do nothing
}
painter->drawPixmap(offset, pixmap);
}