Change page of QstackedWidget with animation - c++

I want to be able to change page of QStackedWidget with some kind of animation (like fade in/out or others...)
after some research I find out maybe its possible with QGraphicsOpacityEffect, then I found this codes in here
Fade In Your Widget
// w is your widget
QGraphicsOpacityEffect *eff = new QGraphicsOpacityEffect(this);
w->setGraphicsEffect(eff);
QPropertyAnimation *a = new QPropertyAnimation(eff,"opacity");
a->setDuration(350);
a->setStartValue(0);
a->setEndValue(1);
a->setEasingCurve(QEasingCurve::InBack);
a->start(QPropertyAnimation::DeleteWhenStopped);
Fade Out Your Widget
// w is your widget
QGraphicsOpacityEffect *eff = new QGraphicsOpacityEffect(this);
w->setGraphicsEffect(eff);
QPropertyAnimation *a = new QPropertyAnimation(eff,"opacity");
a->setDuration(350);
a->setStartValue(1);
a->setEndValue(0);
a->setEasingCurve(QEasingCurve::OutBack);
a->start(QPropertyAnimation::DeleteWhenStopped);
connect(a,SIGNAL(finished()),this,SLOT(hideThisWidget()));
// now implement a slot called hideThisWidget() to do
// things like hide any background dimmer, etc.
but looks like these codes have some problem when used in QWidget inside of QStackedWidget i mean widget successfully fade in and out, but after animation finish if I minimize the windows the widget will disappear completely! (Im still able to see widget in bottom right corner of my window, looks like its pos changed?!)
btw my program is frameless.
thanks for help.
here is a example from my problem
test.cpp
Test::Test(QWidget *parent)
: CustomMainWindow(parent)
{
ui.setupUi(this);
setShadow(ui.bg_app);
connect(ui.close_app_btn, &QPushButton::clicked, this, &QWidget::close);
connect(ui.minimize_app_btn, &QPushButton::clicked, this, &QWidget::showMinimized);
QGraphicsOpacityEffect* eff = new QGraphicsOpacityEffect(this);
ui.checking->setGraphicsEffect(eff); // checking is my widget inside of QStackedWidget.
QPropertyAnimation* a = new QPropertyAnimation(eff, "opacity");
a->setDuration(350);
a->setStartValue(0);
a->setEndValue(1);
a->setEasingCurve(QEasingCurve::InBack);
a->start(QPropertyAnimation::DeleteWhenStopped);
}
CustomMainWindow.cpp
CustomMainWindow::CustomMainWindow(QWidget *parent)
: QMainWindow(parent)
{
setWindowFlags(windowFlags() | Qt::Window | Qt::FramelessWindowHint | Qt::WindowSystemMenuHint);
setAttribute(Qt::WA_TranslucentBackground);
}
void CustomMainWindow::setShadow(QWidget* window)
{
QGraphicsDropShadowEffect* windowShadow = new QGraphicsDropShadowEffect;
windowShadow->setBlurRadius(9.0);
windowShadow->setColor(palette().color(QPalette::Highlight));
windowShadow->setOffset(0.0);
window->setGraphicsEffect(windowShadow);
}
when I run my program with this code, at first its successfully Fade In, but if I for example minimize the window the widget move from its original position to somewhere else, look at this gif

Note: MainWindow is the name of my class.
Header file:
//...
private slots:
void animationStackedWidgets();
void whenAnimationFinish();
//....
CPP file:
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect(ui->button, &QPushButton::clicked, this, &MainWindow::animationStackedWidgets);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::animationStackedWidgets()
{
QGraphicsOpacityEffect *effect = new QGraphicsOpacityEffect(this);
ui->stackedWidget->setGraphicsEffect(effect);
QPropertyAnimation *anim = new QPropertyAnimation(effectSw,"opacity");
anim->setDuration(350);
anim->setStartValue(0);
anim->setEndValue(1);
anim->setEasingCurve(QEasingCurve::InBack);
anim->start(QPropertyAnimation::DeleteWhenStopped);
connect(anim, SIGNAL(finished()), this, SLOT(whenAnimationFinish()));
}
void MainWindow::whenAnimationFinish()
{
ui->stackedWidget->setGraphicsEffect(0); // remove effect
}

Related

qt button added on menu bar

I'm trying to add buttons to a vertical layout in QT.
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
mRootLayout = new QVBoxLayout(this);
setLayout(mRootLayout);
mRootLayout->addWidget(new QPushButton("Button1", this));
mRootLayout->addWidget(new QPushButton("Button2", this));
}
I have 2 problems
1. The buttons are created on top of the menu bar
2. The buttons are not one under the other one.
I'm using a QVBoxLayout.
I think code must be change to:
mRootLayout = new QVBoxLayout(ui->centralWidget);
mRootLayout->addWidget(new QPushButton("Button1", this));
mRootLayout->addWidget(new QPushButton("Button2", this));
It's not necessary do setLayout().

Overlay widgets

I am trying to overlay a few buttons over my video player.
I have added a new class called overlay.cpp that subclassed a QWidget for the overlay purpose.
What I did in my code is to overlay button onto the video. In my centralWidget I have added a verticalLayout and morph it into a QWidget. The video was added into this verticalLayout. Upon program is running, the video is playing well. However, what's not working is the overlay of the button. The background doesn't seem to appear transparent even though it was set. I am not sure what is causing it to not appear transparent.
My code is as follows:
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[]){
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent):QMainWindow(parent),
ui(new Ui::MainWindow){
ui->setupUI(this);
initializeVideo();
initializeButton();
}
MainWindow::~MainWindow(){
delete ui;
}
void MainWindow::initializeVideo(){
QVideoWidget *v_widget = new QVideoWidget;
QMediaPlayer *m_player = new QMediaPlayer;
m_player->setMedia(QUrl::fromLocalFile("C:/user/Desktop/video.wmv"));
m_player->setVideoOutput(v_widget);
ui->verticalLayout->addWidget(v_widget);
m_player->player();
v_widget->show();
}
void MainWindow::initializeButton(){
QFrame *b_frame = new QFrame;
QGridLayout *grid = new QGridLayout;
b_frame->setLayout(grid);
b_frame->setAttribute(Qt::WA_TranslucentBackground, true);
QPushButton *buttonStop = new QPushButton;
buttonStop->setText("STOP");
grid->addWidget(buttonStop, 0, 0, Qt::AlignTop);
overlay *overlay_1 = new overlay;
QGridLayout *gridLayout = new QGridLayout;
gridLayout->addWidget(b_frame);
overlay_1->setLayout(gridLayout);
overlay_1->setParent(ui->verticalWidget);
overlay_1->show();
b_frame->show();
}
overlay.cpp
#include "overlay.h"
overlay::overlay(QWidget *parent): QWidget(parent){
this->setAttribute(Qt::WA_TranslucentBackground, true);
}
Move declaration of QVideoWidget *v_widget and QMediaPlayer *m_player to mainwindow.h like this:
private:
Ui::MainWindow *ui;
QVideoWidget *v_widget;
QMediaPlayer *m_player;
In mainwindow.cpp:
void MainWindow::initializeVideo()
{
v_widget = new QVideoWidget(this);
m_player = new QMediaPlayer(this);
m_player->setMedia(QUrl::fromLocalFile("C:/user/Desktop/video.wmv"));
m_player->setVideoOutput(v_widget);
ui->verticalLayout->addWidget(v_widget);
m_player->play();
}
void MainWindow::initializeButton()
{
QGridLayout *grid = new QGridLayout(v_widget);
QPushButton *buttonStop = new QPushButton(this);
buttonStop->setText("STOP");
grid->addWidget(buttonStop, 0, 0, Qt::AlignTop);
}
This will add "STOP" button on top of QVideoWidget.
Specify widget's parent when crating it. new QVideoWidget(this) will create new QVideoWidget as child of current MainWindow widget. If you are creating child of already visible widget you do not need to call show() on it.

Qt: TextEdit in GraphicsView with weird gray bar below

I'm using QGraphicsView / QGraphicsScene and added a QTestEdit-Widget. Unfortunately, the TextEdit gets rendered with a gray bar below, and I'm unable to get rid of it. Does anyone know how to achieve this?
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QGraphicsView *view = new QGraphicsView(ui->centralWidget);
QGraphicsScene *scene = new QGraphicsScene(0, 0, 2000, 2000, view);
scene->setSceneRect(-100,-100,400,400);
view->setTransformationAnchor(QGraphicsView::NoAnchor);
view->setScene(scene);
QTextEdit *edt_test = new QTextEdit(0);
edt_test->setGeometry(10,20,80,60);
edt_test->setFrameStyle(QFrame::Plain | QFrame::Box);
scene->addWidget(edt_test);
}
using StyleSheet didn't solve the problem, but the following worked fine:
QTextEdit *edt_test = new QTextEdit(0);
QGraphicsProxyWidget *proxy = scene->addWidget(edt_test);
edt_test->setFrameStyle(QFrame::Plain | QFrame::Box);
proxy->setGeometry(QRectF(10,20,80,60));
calling setGeometry based on the ProxyWidget is the solution. Seems weird ...

Qt Get String from C++ Method and DrawText in Widget?

i'm very newbie and lost!
I have a .cpp file in my qt project and my own widget.cpp wich has drawings! Now i want to get the data from the other .cpp file, from a class called, outputtext..which has a method add(name,value) both std string!
Know i want in my widget.cpp to import this stings! I have a form and i put a button on it 'get string'-button!
Know i have
void Widget::on_pushButton_clicked(){
// how can i use Qpainter to deaw the text in my widget?
}
so, this is my widget class:
#include "widget.h"
#include "ui_widget.h"
#include "outputtext.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_pushButton_clicked()
{
//int outputtext.add(name,value);
// i want to say get the name and value from outputtext class and draw it in the widget!
}
and the other cpp file (outputtext) as a method add(name, vale) as string:
unsigned int OutPutText::add( std::string name , std::string value )
{
.....
}
please help!! i think it is easy but I just can't get the painter works from the push-button!
problem solved:
in order to get the text and drawing in the widget from the on_pushButton_clicked, i had to use QPixmap and QGraphicsscene so that i have a Scene for the Paiter and to show the drawing on the widget i set the size for the Pixmap as so as the size of my widget and make the pixmap transparent...then i have to use QGraphicsviewer to let the scene shows on the widget like the code below!
thanks any way...
void Widget::on_pushButton_clicked()
{
QPixmap *pixmap = new QPixmap(this->size());
pixmap->fill(Qt::transparent);
QGraphicsScene *scene = new QGraphicsScene(this);
scene->addPixmap(*pixmap);
QPainter painter(pixmap);
painter.begin(pixmap);
painter.drawPixmap(QPoint(0,0), *pixmap);
painter.drawText(x,y,"my string");
painter.end();
QGraphicsView *view = new QGraphicsView(scene, this);
scene->addPixmap(*pixmap);
view->setStyleSheet("background: transparent");
view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
view->show();
}

QGraphicsView Won't Expand

I'm having extreme trouble getting QWidgets to expand as needed. This isn't the first time I've run into this problem, and last time I solved it by hacking in a large sizeHint(). This is the WRONG approach and I would really like to learn the CORRECT approach.
If anyone could help me out it would be greatly appreciated. Here's what it looks like and the layouts I have written in code. If necessary I can supply the code. Please help me learn Layouts.
Edit: The first layout mock up actually works correctly. I am attaching another layout mockup which causes a problem.
Code. Three classes.
MainWindow Class:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent)
{
QWidget * w = new MainCentralWidget(this);
setCentralWidget(w);
}
MainCentralWidget Class:
MainCentralWidget::MainCentralWidget(QWidget *parent) :
QWidget(parent)
{
SetupLayout();
}
void MainCentralWidget::SetupLayout()
{
QVBoxLayout * main_layout;
QFormLayout * plugin_layout;
//Start
main_layout = new QVBoxLayout();
//Setup the plugin chooser
plugin_layout = new QFormLayout();
QComboBox * plugins_box = new QComboBox();
plugin_layout->addRow("Choose Plugin: ", plugins_box);
QFrame* line = new QFrame();
line->setFrameShape(QFrame::HLine);
line->setFrameShadow(QFrame::Sunken);
plugin_layout->addRow(line);
main_layout->insertLayout(0, plugin_layout);
main_layout->insertWidget(1, new SubWidget());
//Finish
setLayout(main_layout);
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
}
SubWidget Class:
SubWidget::SubWidget(QWidget *parent) :
QWidget(parent)
{
setStyleSheet("QWidget { background: yellow }");
setMaximumSize(10000,10000);
setMinimumSize(100,100);
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
SetupLayout();
//setMaximumSize(10000,10000);
}
void SubWidget::SetupLayout()
{
QHBoxLayout main_layout;
main_layout.setAlignment(Qt::AlignTop | Qt::AlignLeft);
main_layout.addWidget(&m_graphics_view);
m_graphics_view.setMaximumSize(10000,100000);
setLayout(&main_layout);
}
void SubWidget::SetupLayout()
{
QHBoxLayout main_layout;
main_layout.setAlignment(Qt::AlignTop | Qt::AlignLeft);
main_layout.addWidget(&m_graphics_view);
m_graphics_view.setMaximumSize(10000,100000);
setLayout(&main_layout);
}
Your main_layout gets destroyed immediately after SetupLayout finished, as it goes out of scope. So, actually, your SubWidget has no any layout. That is why widgets are shown incorrectly.