Qt Set QTableView background image without stylesheet - qt

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();
}

Related

gif image in QLabel

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);

QAxWidget don’t display

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);
}

Qt::Pixmap in Qwidget doesn't show up in MainWindow

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);

Animating image replacement in Qt

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.

QWidget/QFrame not showing background or border when added to layout

I have a QFrame derived object:
class SubjectLineDisplay : public QFrame
{
Q_OBJECT
private:
// Members
public:
explicit SubjectLineDisplay(const QString&, const QString&, quint32, QWidget *parent = 0);
};
In the constructor, I set a background for it and a border:
QPalette p(palette());
p.setColor(QPalette::Background, QColor(255, 255, 255));
setPalette(p);
setLayout(mainLayout); // The mainLayout is a VBoxLayout which is a collection of a few QLabels
setFixedHeight(lTitle->size().height() + lId->size().height());
When i do this in main():
SubjectLineDisplay* x = new SubjectLineDisplay("NETWORK", "Network Centric Programming", 4);
x->show();
The widget shows up in a window, with the background and frame displaying properly, just as I would want. However, when I add it to another layout to show it:
SubjectLineDisplay* lineDisplay = new SubjectLineDisplay(
subjectNameLE->text(), idLE->text(), creditSpin->value()
);
emit newSubjectAdded(Course(subjectNameLE->text(), idLE->text(), creditSpin->value()));
subjectNameLE->clear();
creditSpin->setValue(3);
idLE->clear();
subjectLineLayout->addWidget(lineDisplay); //Adding the widget to a layout
Now, I don't see the frame or the border. How do I get the layout to display the frame and the border? What am I doing wrong?
Could you try using setAutoFillBackground(true)?
For as far as I'm aware foregrounds are always drawn, but backgrounds are not.

Resources