the code as follow doesn't create the animation... But if the QPropertyAnimation is a new instance , then it can.. Why? what is the difference ? Thank you...
QRect orgRect = this->geometry();
QRect endRect = btExpand ? QRect(*ptNotePadPot, COLLAPSE_SIZE) :
QRect(*ptNotePadPot, EXPAND_SIZE);
/*
QPropertyAnimation* amt = new QPropertyAnimation(this, "geometry", this);
amt->setDuration(10000);
amt->setStartValue(orgRect);
amt->setEndValue(endRect);
amt->start();
*/
QPropertyAnimation amt(this, "geometry", this);
amt.setDuration(10000);
amt.setStartValue(orgRect);
amt.setEndValue(endRect);
amt.start();
After it starts, QProperyAnimation will create its own timer and run outside your main thread.
QPropertyAnimation amt(this, "geometry", this);
it will be destroyed after run pointer exit your function scope.
otherwise if u use
QPropertyAnimation* amt = new QPropertyAnimation(this, "geometry", this);
you will create one animation object in the memory to work and its pointed by amt pointer.
the pointer will be deleted after run pointer exit your function scope, not the QPropertyAnimation object.
but it will be a zombie in the memmory if you not delete it.
the best way is, use a class variable for QPropertyAnimation pointer. so you can delete the object in the pointer after program closed or when ever u want.
i hope it helps..
sory for my bad english.
A better way to solve this without memory leak is to call the start() method like this:
animation->start(QAbstractAnimation::DeleteWhenStopped);
Related
I've experienced a weird crash when trying to find a QLineEdit in a QFormLayout.
Firstly, I created a QFormLayout and set a name for it:
QFormLayout *charColLayout = new QFormLayout; charColLayout->setObjectName("charColLayout");
Then, I created a QLineEdit, modified it a bit and add it in to the layout, and I also give it a name:
QLineEdit *delim = new QLineEdit;
delim->setMaxLength(1);
delim->setMaximumWidth(100);
delim->setText("/");
delim->setObjectName("delEdit");
charColLayout->addRow("Delimiter", delim);
Afterward, in a completely different function, I re-searched that layout with findChild():
QFormLayout *charcoal = secondHoriField->findChild<QFormLayout *>("charColLayout", Qt::FindChildrenRecursively);
It should be noted that secondHoriField is just a normal QLayout which my QFormLayout is located in.
Finally, I attempted to find that QLineEdit:
QLineEdit *delimEdit = charcoal->findChild<QLineEdit*>("delEdit", Qt::FindChildrenRecursively);
if (delimEdit == nullptr) {cerr << "error\n";} //debug
string curDelim = qStrToStr(delimEdit->text());
And it surprisingly came down with a crash, and as the output shown, it's because the delimEdit is null.
18:06:10: Starting D:\...\build-cryptog-Desktop_Qt_5_15_2_MinGW_64_bit-Debug\debug\cryptog.exe ...
error
18:06:17: The program has unexpectedly finished.
18:06:17: The process was ended forcefully.
18:06:17: D:\...\build-cryptog-Desktop_Qt_5_15_2_MinGW_64_bit-Debug\debug\cryptog.exe crashed.
But when I switched the findChild() function for this rather bruteforce-y line:
QLineEdit *delimEdit = dynamic_cast<QLineEdit*>(charcoal->itemAt(1)->widget());
cerr << qStrToStr(delimEdit->objectName()) << endl; //debug line
The program ran fine, and it showed the same name I set for the QLineEdit:
18:12:02: Starting D:\...\build-cryptog-Desktop_Qt_5_15_2_MinGW_64_bit-Debug\debug\cryptog.exe ...
delEdit
18:12:11: D:\...\build-cryptog-Desktop_Qt_5_15_2_MinGW_64_bit-Debug\debug\cryptog.exe exited with code 0
Why did this happened?
Another note: qStrToStr() is a function I implement to convert QString to std::string, and I have hand-checked it.
While findChild is a QObject method the itemAt is a QFormLayout method.
QObject::findChild
QFormLayout::itemAt
With addRow you add an item to the QFormLayout. This does not make it a child in the context of the QObject.
QFormLayout::addRow
The purpose of the QFormLayout is to organize the positioning of QWidgets, it is not meant to serve as a container. Maybe you could check whether the top level QWidget (e.g. QMainWindow) holding the QFormLayout would be a better choice as a parent for the QLineEdit.
Assuming you have some kind of QMainWindow:
QMainWindow myMainWindow;
// ...
QLineEdit *delim = new QLineEdit(&myMainWindow);
delim->setObjectName("delEdit");
//...
In another location:
auto delimEdit = myMainWindow.findChild<QLineEdit*>("delEdit");
I didn't find a proper solution to this problem, so I hope somebody can give me an answer to my problem:
I am using a normal QTreeWidget, but as items I use an own subclass of QTreeWidgetItem (because I needed to store some other information in the item). Now I want to use the itemClicked() signal by the QTreeWidget, but I think my slot doesn't get any signal and I think it has to do with the signature of itemClicked(), since it sends a QTreeWidgetItem and of course not my own subclass.
Is it possible that QTreeWidget doesn't detect a click on my own subclass items?
Here is my connection:
connect(treeWidget, SIGNAL(itemClicked(QTreeWidgetItem *)), this, SLOT(displayTransformData(QTreeWidgetItem*)));
And here is my slot:
void GUI::displayTransformData(QTreeWidgetItem* item) {
cout << "test" endl;
Q_actorTreeWidgetItem* actor_item = dynamic_cast<Q_actorTreeWidgetItem*>(item);
vtkSmartPointer<vtkActor> actor =
vtkSmartPointer<vtkActor>::New();
actor = actor_item->getActorReference();
double* position = new double[3];
position = actor->GetOrigin();
x_loc->setText(QString(std::to_string( position[0]).c_str() ));
}
I'm already trying to cast the item that I could get from the signal into my own subclass, but the slot function is never called, because the test from my cout line doesn't appear in the console.
I'm very grateful for every help!
The problem is your incorrect SIGNAL specification,
SIGNAL(itemClicked(QTreeWidgetItem *))
You should probably see a warning message at the console along the lines of:
QObject::connect: No such signal
tree_widget::itemClicked(QTreeWidgetItem *) in ...
From the documentation the actual signal spec is
void QTreeWidget::itemClicked(QTreeWidgetItem *item, int column)
So, using the old Qt4 syntax you need
connect(treeWidget, SIGNAL(itemClicked(QTreeWidgetItem *, int)),
this, SLOT(displayTransformData(QTreeWidgetItem*)));
If possible, however, you should make use of the newer Qt5 signal/slot syntax
connect(treeWidget, &QTreeWidget::itemClicked, this, &GUI::displayTransformData);
I have an application which contains such lines.
emit WindowAdded(settings->WindowType);//!!!!!!!!!!!!!!
MyWindow *widget = new MyWindow(0,settings,currentWindowIndex);
The signal changes value of currentWindowIndex, but it didn't work because of slot, it doesn't change its value in time. Some one advices me to use QEventLoop, but i don't understand how to do this. Give me an example, please.
Another part of the code:
connect(area,SIGNAL(WindowAdded(QString)),this,SLOT(addWindowOnTab(QString)));
void WorkSpace::addWindowOnTab(QString title)
{
qint32 i = TabsList->addTab(title);/////!!!!!!!!!!!!!!!!!!!!!!!!!
emit addedWindowIndex(i);
TabsList->setVisible(true);
}
connect(this,SIGNAL(addedWindowIndex(qint32)),area,SLOT(WindowIndexChanged(qint32)));
void MyMdiArea::WindowIndexChanged(qint32 index)
{
currentWindowIndex=index;
}
I think it can help.
MyMdArea is сlass inherited from QMdiArea, WorkSpace is a QWidget, TabsList is a QTabBar.
And there is another fact: I tried to understand execution sequence of slots and added some lines to code:
QLabel *n= new QLabel("1");
n->show();
after emiting WindowAdded signal
QLabel *n= new QLabel("2");
n->show();
after emiting addedWindowIndex signal
and
QLabel *n= new QLabel("3");
n->show();
after changing currentWindowIndex's value
and that is what i saw "1 2 3" and its exploded my brain. Maybe i don't understand something?
I am trying to make two timers using QLCDNumber. These timers will be generated as a part of my status bar, in a dll. I have two LCDNumber displays. lcdNumber1 will start at a specified time (e.g. 12:00:00). lcdNumber2 will start at 0 (e.g. 00:00:00).
How am I able to create a timer for lcdNumber2 and let it to start ticking?
How can I add lcdNumber2's timer to lcdNumber1? Or can I create a timer for lcdNumber1 to start ticking from the specified time?
Could anyone please help?
QLCDNumber *lcdNumber1 = new QLCDNumber;
lcdNumber1->setNumDigits(8);
lcdNumber1->display(12:00:00);
statusBar->addWidget(lcdNumber1);
QLCDNumber *lcdNumber2 = new QLCDNumber;
lcdNumber2->setNumDigits(8);
lcdNumber2->display(00:00:00);
statusBar->addWidget(lcdNumber2);
Inherit QLCDNumber adding variable time to hold current time and another slot tick()
QLCDNumber_my::tick(){
time++;
this->display(time);
}
and then
QLCDNumber_my *lcdNumber1 = new QLCDNumber_my;
lcdNumber1->setNumDigits(8);
lcdNumber1->display(12:00:00);
statusBar->addWidget(lcdNumber1);
QTimer *timer = new QTimer(this);
timer->start(1000);
connect(timer, SIGNAL(timeout()), lcdNumber1, SLOT(tick()));
QLCDNumber is simple displaying widget, it cannot run, to produce time change you need to use sepatare timer (QTimer).
i m facing problem in giving animation to progressbar in QT.
where is the mistake in the following code, i am getting continues progress bar, but its not animating
QApplication a(argc, argv);
QProgressDialog *dialog = new QProgressDialog();
QProgressBar *pbar = new QProgressBar(dialog);
pbar->setMinimum(0);
pbar->setMaximum(0);
pbar->setTextVisible(false);
QDesktopWidget *desktop = QApplication::desktop();
QRect rect = desktop->geometry();
pbar->setGeometry(rect.left(),rect.top(),rect.right(),rect.bottom()-300);
pbar->show();
dialog->setBar(pbar);
dialog->showMaximized();
dialog->exec();
return a.exec();
I tried this code on WinXP with Qt 4.5.3 and it works as expected.
I cannot give you a solution but i have a suggestion:
You don't need to set a QProgressBar to QProgressDialog, it already has its own.
Removing the code for QProgressBar, the code below does the same thing with your original code on my machine.
QApplication a(argc, argv);
QProgressDialog *dialog = new QProgressDialog();
dialog->setMinimum(0);
dialog->setMaximum(0);
dialog->showMaximized();
dialog->exec();
return a.exec();
If you're using the Windows Vista theme (QWindowsVistaStyle) then there's a bug that means indeterminate progress bars don't animate. I've written up the bug here, complete with simple patch: http://bugreports.qt-project.org/browse/QTBUG-10984
Dudes, what exactly do you think that a progress bar does? It is supposed to show the user that an activity is ongoing and also what is the current progress state.
Your code
QProgressDialog *dialog = new QProgressDialog();
dialog->setMinimum(0);
dialog->setMaximum(0);
would indicate that a certain operation will start with status 0 and will end when the status (or current value) reaches value ... 0. And you want some animation going with that?
See an example at http://doc.trolltech.com/4.6/qprogressdialog.html#details
Basically you should create a progress dialog with a min and a max value
QProgressDialog *dialog = new QProgressDialog();
dialog->setMinimum(0);
dialog->setMaximum(100);
Then have the actual progress value updated (e.g. on a timer which triggers the perform slot) in order to have it represented in the progress bar:
void Operation::perform()
{
dialog->setValue(steps);
//... perform one percent of the operation
steps++;
if (steps > dialog->maximum())
t->stop();
}
A series of updates, with progressively increasing progress value, will create the animation effect you want.
Obviously tagging this with Symbian is pure wrong, this is not at all Symbian specific. Nor is it Qt 4.x specific, hell ... it's not even Qt specific, it's basically a logic issue. ;)