How to add effects in QTDialog during show/hide? - c++

Is there any way to add effects like dialog coming out to maximum size from tiny size when users clicks to show dialog !
like in iphoto when we request to open a dialog, it comes out in the same way!!!
The code which i'm using is :
fade_effect = new QGraphicsOpacityEffect(this);
this->setGraphicsEffect(fade_effect);
animation = new QPropertyAnimation(fade_effect, "opacity");
animation->setEasingCurve(QEasingCurve::InOutQuad);
animation->setDuration(5000);
animation->setStartValue(1);
animation->setEndValue(0.01);
animation->start(QPropertyAnimation::DeleteWhenStopped);
this->setWindowOpacity(0.5);
//this->hide();
//QDialog::reject();
Its not working in hiding case.

Qt Animation Framework gives you a lot of tools to create animation effects. Here is a sample how you can achieve your aim with QPropetyAnimation :
void YourWindowClass::showEvent(QShowEvent* e)
{
//create animation for "geometry" property
QPropertyAnimation *animation = new QPropertyAnimation(this, "geometry");
//duration in ms
animation->setDuration(500);
//starting geometry
QRect startRect(900,500,100,100);
//final geometry
QRect endRect(750,350,400,400);
animation->setStartValue(startRect);
animation->setEndValue(endRect);
//starts animation which will be deleted when finished
animation->start(QAbstractAnimation::DeleteWhenStopped);
}

Related

Qt how to use paintEvent function to refresh two or more widgets silmultaneously

Now I am using Qt5 to draw Kline of stocks. Two classes are defined for price bar and volume bar, then I add them to a widget by a QSplitter. However, When I move mouse forward or backward and the price-bar chart updates, the volume-bar section will not repaint simultaneously until I put mouse under volume widget. I tried some ideas, but it didn't work. Many thanks.
A part of codes like this:
pvolume = new VolumeBar(this);
pvolume->setObjectName(tr("volume_bar"));
pvolume->setFocusPolicy(Qt::StrongFocus);
pkline = new PriceBar(this);
pkline->setObjectName("price_bar");
pkline->setFocusPolicy(Qt::StrongFocus);
QSplitter *splitterMain = new QSplitter(Qt::Vertical, 0);
splitterMain->insertWidget(0, pkline);
splitterMain->insertWidget(1, pvolume);
splitterMain->setStretchFactor(0, 4);
splitterMain->setStretchFactor(1, 1);
For pricebar, the paintEvent function is overrided as follows,
void PriceBar::paintEvent(QPaintEvent *event)
{
KLineGrid::paintEvent(event); // parent of VolumeBar and PriceBar
drawLine(); // draw price bar
}
For VolumeBar, it is overrided like this,
void VolumeBar::paintEvent(QPaintEvent *event)
{
KLineGrid::paintEvent(event);
drawYtick(); // y axis
drawVolume();
}

QtChart - C++ - Saving a chart which wasn't displayed

I'm trying to save a chart to a file, in a QTextDocument in this example :
QTextDocument doc("Frame rate test\n");
QTextCursor cursor(&doc);
cursor.movePosition(QTextCursor::End);
if (getTestFinishedStatus())
{
QPixmap pix = _pFrameRateChart->grab(); //_pFrameRateChart is QChartView
cursor.insertImage(pix.toImage());
}
QTextDocumentWriter docWriter;
docWriter.setFileName("framerate.odf");
docWriter.setFormat("ODF");
docWriter.write(&doc);
The problem is the result isn't same if I'm displaying the chart in an ui.
Here is the result when not displayed :
Here is the result when displayed :
Obviously I would like to have the second result even when I don't add the ChartView to a widget to display it on an ui.
I've tried resizing the QChartView, resizing the QChart, adding the Chart to a temporarly widget and QVBoxLayout then saving it, showing temporarly the QChartView before saving it etc... but didn't managed to get a good result.
I use the following code to render a QGraphivsView on a Pixmap, since QtCharts is based on QGraphivsView, I think this will also work.
Try to render the image instead of trying to grab the pixmap.
void Printer::putProfileImage(QRect profilePlaceholder, QRect viewPort, QPainter *painter, QGraphivsView* profile)
{
int x = profilePlaceholder.x() - viewPort.x();
int y = profilePlaceholder.y() - viewPort.y();
QRect pos(x, y, profilePlaceholder.width(), profilePlaceholder.height());
profile->render(painter, pos);
}
I didn't find any easy way to this, so here's my solution, which is more like a workaround though :
QPixmap ChartView::getChartPixmap()
{
QWidget* w = new QWidget; //creating a temporary widget, which will enable to display the chart
w->resize(REPORT_IMAGE_WIDTH, REPORT_IMAGE_HEIGHT);
QVBoxLayout *vl;
vl = new QVBoxLayout(w);
vl->addWidget(this); //'this' being the QChartView
w->show(); //showing the widget so it is resized and can be grabbed with the correct dimensions
QTest::qWait(500); //we need to wait for a little for the graph to be drawn otherwise you'll still have the same size problem
QPixmap pixmap = w->grab(); //retrieve the pixmap
w->hide(); //hiding the widget
return pixmap;
}
It's working but you'll have a small window opened with the graph for 500 ms.

Identify which QPixmapItem has been selected

I am adding QGraphicsPixmapItems to my scene, and I can see that when I pick on the item, it gets the white dashed selection rectangle, but I'm struggling to get any data from this selection. Here is how I'm adding it to the scene.
void MainWindow::drawImage(curTarget *newTarget){
QGraphicsPixmapItem *tgt = new QGraphicsPixmapItem;//new pixmap
tgt = scene->addPixmap(newTarget->myIcon);//assign pixmap image
tgt->setFlag(QGraphicsItem::ItemIsSelectable, true);
scene->addItem(tgt);
}
Each PixmapItem that I add to the scene has struct data associated with it, and I need to be able to retrieve that data when I select on the QGraphicsPixmapItem inside of the QGraphicsScene. If the selection rectangle is showing up when the pixmapitem is selected, isn't there some easy way to return information to me based on that fact? A Pointer to what is selected perhaps?
I do have a mousePressEvent method implemented but I'm struggling getting anything relevant with that.
void MainWindow::mousePressEvent(QMouseEvent *event){
qDebug() << "Clicked" << endl;
}
When I run the app, I see Clicked everywhere in my scene except when I click on my pixmapitems.
I've tried every version of the mousePressEvents available and the ones that actually do something, only do something as long as I don't press on my pixmapitems.
Thank to the help I received in my comments, I will post up what ultimately worked for me.
void MainWindow::drawImage(curTarget *newTarget)
{
QGraphicsPixmapItem *tgt = new QGraphicsPixmapItem
tgt = scene->addPixmap(newTarget->myIcon);
tgt->setFlag(QGraphicsItem::ItemIsSelectable, true);
scene->addItem(tgt);
}
With the new function added...
void MainWindow::whatIsSelected(){
QDebug() <<scene->selectedItems() << endl;}
And then I made the connection of the scene to the window elsewhere...
QObject::connect(scene, SIGNAL(selectionChanged()), this, SLOT(whatIsSelected);

QT QGraphicsView rotation

Disclaimer: I am pretty much a beginner with QT.
I've been struggling for some time to rotate a QGraphicsView (no 3D rotation) but, despite what i do, it doesn't work. I have tried:
QTransform transform;
transform.rotate(45);
ui->graphicsView->setTransform(transform);
or more simply:
ui->graphicsView->rotate(45);
These seem like very straightforward ways to do it that should work, but for some reason, whenever i run it, the QGraphicsView doesn't rotate at all. If possible, i'd like some direct and easy to understand code snippets, and/or what i'm doing wrong.
EDIT: This is the code in the widget cpp file i have problems with. It should be a simple timer with an animated hourglass icon. It gets repeated every .5 seconds.
void Widget::timerEvent(QTimerEvent *event)
{
++timeFlag;
++timerFlag;
if (timerFlag < 115){
animateTimer = QString("\":/new/100/timerFrames/timerIconFrame%1.png\"").arg(timerFlag);
QPixmap pix(animateTimer);
pixmapitem.setPixmap(pix);
scene.addItem(&pixmapitem);
ui->graphicsView_2->setScene(&scene);
}
if (timerFlag >= 115 && timerFlag < 119){
//
}
if(timerFlag == 119){
ui->graphicsView_2->setStyleSheet("border-image:url(:/new/100/timerIconPix.PNG);border:0px;}");
}
if(timerFlag == 120){
timerFlag = 0;
}
if (timeFlag==2){
timeFlag = 0;
if(sec>=10){
ui->label_2->setText(QString("%1:%2").arg(min).arg(sec));
} else {
ui->label_2->setText(QString("%1:0%2").arg(min).arg(sec));
}
++sec;
if (sec == 60) {
sec = 0;
++min;
}
}
}
You're merely decorating the QGraphicsView using the style mechanism. You could have used a plain QWidget instead, since you don't use any graphics view functionality. None of the images in the stylesheet are what the view actually displays. The image must be on the scene displayed by the view.
Set the image on a QGraphicsPixmapItem, add that item to a scene, set the scene on the view, and then the transformations will work. You can then keep replacing the pixmap in the timer handler.
Finally, you must also check the timer id in the timerEvent. I assume that you're using a QBasicTimer, say called m_timer, you'd then check as follows:
void Widget::timerEvent(QTimerEvent * ev) {
if (ev->timerId() != m_timer.timerId()) return;
... // rest of the code
}
As you can see, the code that you've not included in the original question was absolutely essential! Without it, the question was wholly off-topic.
You need to implement a QGraphicsView, a QGraphicsScene and then add something that inherits from QGraphicsItem to that scene to rotate.
Here is an example that rotates a QWidget in a QGraphicsView:
QGraphicsView* view = new QGraphicsView(parent);
QGraphicsScene* scene = new QGraphicsScene(view);
view->setScene(scene);
// Widget to rotate - important to not parent it
QWidget* widget = new QWidget();
QProxyWidget proxy_widget = scene_->addWidget(widget);
QPropertyAnimation* animation = new QPropertyAnimation(proxy_widget, "rotation");
animation->setDuration(5000);
animation->setStartValue(0);
animation->setEndValue(360);
animation->setEasingCurve(QEasingCurve::Linear);
animation->start(QAbstractAnimation::DeleteWhenStopped);

Widget not shown in QMainWindow

Good evening,
the aim is to have a mainwindow (created without Designer but by coding) with three sections next to each other:
a list of data points (vector)
statistics about the data points
a graphical summary (histogram)of the data
I have started to create my own widget do draw a diagram (just a line for test purposes so far).
However, while the tableview widget is shown, the "diagram" widget (instance of class histogram) is not shown (should be a third vertical column).
A very similar problem in Stackoverflow gave me some direction. But while it helped me to display the widget with the table, I did not figure out how to show my custom widget.
post: widgets not shown in qt main window
I have also checked literature (Summerfield and Qt4 Hui Entwicklung mit C++ by Jürgen Wolff), but they only have examples with only one central widget.
#include "mainwindow.h"
#include <QApplication>
#include <QDebug>
MainWindow::MainWindow(QMainWindow *parent, Qt::WindowFlags flags) : QMainWindow(parent, flags)
{
mainWidget = new QWidget(this);
setCentralWidget(mainWidget);
tableWidget = new QTableWidget(mainWidget); // QTableWidget to display the data vector
//...
// here comes code to fill the table...
//...
// result labels
lbl_sampleSize = new QLabel("sample size");
lbl_meanValue = new QLabel("mean");
lbl_sigma = new QLabel("sigma");
lbl_andersonDarling = new QLabel("Anderson Darling");
lbl_pValue = new QLabel("p-value for Anderson-Darling");
rightLayout = new QVBoxLayout(); // a vertical layout to contain labels
rightLayout->addWidget(lbl_sampleSize);
rightLayout->addWidget(lbl_meanValue);
rightLayout->addWidget(lbl_sigma);
rightLayout->addWidget(lbl_andersonDarling);
rightLayout->addWidget(lbl_pValue);
rightLayout->addStretch();
//diagram
diagram = new Histogram(mainWidget);
mainLayout = new QHBoxLayout(mainWidget);
mainLayout->addWidget(tableWidget,0);
mainLayout->addLayout(rightLayout,0);
mainLayout->addWidget(diagram, 0);
//mainWidget->setLayout(mainLayout);
}
screenshot:
remark:
with this code
//diagram
diagram = new Histogram();
mainLayout = new QHBoxLayout(mainWidget);
mainLayout->addWidget(tableWidget,0);
mainLayout->addLayout(rightLayout,0);
//mainLayout->addWidget(diagram, 0);
//mainWidget->setLayout(mainLayout);
diagram->show();
I was able to create a separate Widget with the test diagram.
(removed the parent information and called diagram->show())
Just set the minimum size (QWidget::setMinimumSize()):
diagram->setMinimumSize(100, 100);
More control over the widget sizing can be achieved through its size policy.