Here is another newbie to Qt.
What I need to do is to have a scrollable Area in the center of MainWindow, which displays images, and allows user to paint on the image.
Since I cannot add a QPixmap directly to a scrollable Area, I tried to create a subclass of QWidget, like below:
class Canvas: public QWidget
{
public:
Canvas(){
image = new QPixmap(480,320);
image->fill(Qt::red);
}
QPixmap *image;
};
Then I declared Canvas *c in the header file.
In the implementation, I wrote:
canvas = new Canvas;
setCentralWidget(canvas);
However, apparently this does not help to show up the QPixmap. I do not know what to do.
You don't need to subclass QWidget for this. QPixmap is not a widget, so it is not shown anywhere. You need to add your pixmap to some widget, this will work:
in header:
QLabel* imageLabel;
in cpp:
imageLabel = new QLabel(this);
QPixmap image(480,320);
image.fill(Qt::red);
imageLabel->setPixmap(image);
setCentralWidget(imageLabel);
Related
I have inherited the QLabel to create my own class of QLabel, The code is below:
class myLabel : public QLabel
{
Q_OBJECT
public:
explicit myLabel(QWidget *parent=nullptr): QLabel(parent){ setFrameShape(QFrame::Box);}
QLabel insideLabel;
};
As you can see, My class has one QLabel member inside.
Now, What I have done is that I created the object of my class and assign a image to it using setPixmap() and also assign a image to my QLabel member inside my class. The code is below:
QFile file("file.png");
ui->setupUi(this);
//Creatig instance of my QLabel class and setting one image to it.
myLabel *label=new myLabel(this);
label->setPixmap(QPixmap("someImagePath"));
//Assining image to my class QLabel member.
label->insideLabel.setPixmap(QPixmap("someImagePath"));
//saving file.
label->pixmap()->save("imageName","png",-1);
So when I save the image it only save the image of my QLabel class object QPixmap instead of saving both of my label image as the insideLabel is present above the my label class object as it is it's member. How can i save both images of my labels as one image.
Your code is not trying to save a QLabel, you are trying to save the pixmap property of a QLabel, those are two very different things.
A QLabel is a widget that can be rendered on a paint device. You should read the documentation about the QWidget subsystem:
Qt Widgets module
I see some problems with your code, the inside widget has no parent, and in your case I think that is a problem, but explaining that is beyond your question.
If what you want is to render the widget into an image file, you could do something like this:
QPixmap pixmap(Widget->size());
Widget->render(&pixmap);
pixmap.save("widget_render_file.png");
If you want to compose an image you can directly draw on a painter attached to a pixmap like this:
QPixmap pixmap(100,100);
QPainter painter(pixmap);
painter.setPen (...);
painter.drawPixmap (...);
painter.end();
pixmap.save(...);
You should also check documentation on QPainter and QPixmap, there's a lot of useful drawing/painting functions.
I just saved the needed portion of my Widget window as image, below is my code
label=new myLabel(this);
label->setGeometry(50,50,300,300);
label->setPixmap(QPixmap("/home/vinay/Pictures/exp.png").scaled(label->width(),label->height()));
label->insideLabel=new QLabel(this);
label->insideLabel->setGeometry(50,50,50,50);
label->insideLabel->setPixmap(QPixmap("/home/vinay/Pictures/exp2.png"));
label->insideLabel->setFrameShape(QFrame::Box);
label->insideLabel->setLineWidth(3);
//Assining image to my class QLabel member.
//saving file.
label->pixmap()->save("imageName","png",-1);
//ui->myWidget->grab().save("image.png");
QRect r(50,50,300,300);
Widget::grab(r).save("image.png");
I want to set a background image to my QTableView.
Inside the function i create a test QWidget and apply the image and it works perfectly.
The fp_widget i pass in is QTableView and here comes the problem.
The image is not shown / applied to the QTableView.
void setBackgroundImage(QWidget *fp_widget, const QPixmap &image)
{
QPalette palette;
palette.setBrush(QPalette::Background, image);
fp_widget->setPalette(palette);
QWidget *test = new QWidget;
test->setPalette(palette);
test->resize(800,800);
test->show();
}
I want to add a gif animated image in QLabel that add into the QGraphicsScene.
My code is here:
QLabel *lbl = new QLabel;
QMovie *mv = new QMovie(":/Images/sun.gif");
mv->start();
lbl->setWindowFlags(Qt::FramelessWindowHint);
lbl->setMask((new QPixmap(":/Images/sun.gif"))->mask()); // for create transparent for QLabel image
lbl->setMovie(mv);
lbl->setGeometry(10,10,10,10);
scene.addWidget(lbl);
but when I run that it will transparent with first frame of that gif and when the gif is running the photo will not show completely and it will run with transparented area in the first frame.
How can I solve that?
Thanks
The problem is that QLabel has window background by default. You're trying to remove it by do it incorrectly:
FramelessWindowHint doesn't make sense here, since it's only used for top level widgets, and a widget added to scene is technically hidden and doesn't have system window frame. This line should be removed.
setMask does exactly what you describe it does. Since QPixmap is not animated, its mask is the alpha mask of the first frame of animation. And you permanently apply this mask to the label. It's not surpising that it works, but obviously it's not what you want. This line should also be removed.
setGeometry line is incorrect. It prevents picture from being visible for me. Label has good size by default and there is no need for setGeometry. If you want to scale or move the item on the scene, you can do it after addWidget as for any other QGraphicsItem. E.g. addWidget(lbl)->setPos(10, 10).
The magic bullet you need is WA_NoSystemBackground. It disables background painting for QLabel completely. So, the full code would be:
QLabel *lbl = new QLabel;
QMovie *mv = new QMovie("c:/tmp/sun.gif");
mv->start();
lbl->setAttribute(Qt::WA_NoSystemBackground);
lbl->setMovie(mv);
scene.addWidget(lbl);
It works fine for me. However I consider it over-complicated. You should not use proxy widgets in scene unless necessary. You can easily add a movie using QMovie and QGraphicsPixmapItem and switching pixmaps as movie frames change. I wrote a convenient class for this:
Header:
class GraphicsMovieItem : public QObject, public QGraphicsPixmapItem {
Q_OBJECT
public:
GraphicsMovieItem(QGraphicsItem* parent = 0);
void setMovie(QMovie* movie);
private:
QMovie* m_movie;
private slots:
void frameChanged();
};
Source:
GraphicsMovieItem::GraphicsMovieItem(QGraphicsItem *parent)
: QGraphicsPixmapItem(parent), m_movie(0) {
}
void GraphicsMovieItem::setMovie(QMovie *movie) {
if (m_movie) {
disconnect(m_movie, SIGNAL(frameChanged(int)), this, SLOT(frameChanged()));
}
m_movie = movie;
if (m_movie) {
connect(m_movie, SIGNAL(frameChanged(int)), this, SLOT(frameChanged()));
}
frameChanged();
}
void GraphicsMovieItem::frameChanged() {
if (!m_movie) { return; }
setPixmap(m_movie->currentPixmap());
}
Usage:
QMovie *mv = new QMovie("c:/tmp/sun.gif");
GraphicsMovieItem* item = new GraphicsMovieItem();
item->setMovie(mv);
scene.addItem(item);
I used QWidget show as a dialog. And put QAxWidget as a subwidget.
But if I set the parent widget transparent, the QAxWidget will not display.
QWidget* widget = new QWidget;
widget->setAttribute(Qt::WA_TranslucentBackground);
......;
QAxWidget* axieBrowser= new QAxWidget(widget);
axieBrowser->setControl(QString::fromUtf8("{8856F961-340A-11D0-A96B-00C04FD705A2}"));
axieBrowser->dynamicCall("Navigate(const QString&)", "www.google.com");
I try if you use other widget, that will display, only QAxWidget don’t display! How could I fi
xed that?
#Dariusz Scharsig I use this function to force the QWidget fresh because repaint() is no effect.
void CMyDialog::changeRectToFresh()
{
this->showNorMal();
QRect rect = this->geometry();
this->setGeometry(rect.adjusted(-1,-1,1,1);
//recover
this->setCeometry(rect);
}
I'm trying to animate the change of a QPixmap, inside QLabel.
I have MainWindow which holds several objects that derive from QScrollArea. Each of these holds a QLabel member.
Using mousePressEvent() I am able to replace the picture of each QLabel using setPixmap(). However, that simply switches the image in each QLabel, while what I would like to achieve is an animation where a new image slides over the existing one.
First I tried using a QTimeLine to draw the QPixmap on the QLabel myself (I've created a class that derives from QLabel for that, and wrote my own setPixmap()) but that didn't work. Next I tried using QPropertyAnimation but it can't construct on a Pixmap without me implementing a sub class for that as well.
Any thoughts or ideas are appreciated.
You will need a QObject with a property that can be animated, and generates the intermediate frames for the animation. An incomplete example:
class LabelAnimator : public QObject
{
Q_OBJECT
Q_PROPERTY(float progress READ progress WRITE setProgress)
public:
LabelAnimator(QLabel* label) : mProgress(0.0f),
mLabel(label),
mAnimation(new QPropertyAnimation(this, "progress", this)
{
mAnimation->setStartValue(0.0f);
mAnimation->setEndValue(1.0f);
}
void setProgress(float progress) {
mProgress = progress;
QPixmap pix = mOriginalPixmap;
int offset = - mLabel->width() * (1.0f-progress);
QPainter painter(&pix);
painter.paint(off, 0, mNewPixmap);
painter.end();
mLabel->setPixmap(pix);
}
void setPixmap(const QPixmap& pix) {
mOriginalPixmap = mLabel->pixmap();
mNewPixmap = pix;
mAnimation->start();
}
};
QLabel was never designed for such uses. Draw your QPixmaps inside a QGraphicsView, it is far more focused towards rendering effects and animations.