I'm trying to put an animated gif into my program.
However, when I follow the proper syntax
QMovie *hit1=new QMovie("BadExplosion.gif");
QLabel *processLabel=new QLabel(this);
processLabel->setMovie(hit1);
hit1->start();
in the
void TestApp::draw()
{
//this code and other drawing code here
}
I run into the error
error C2664: 'QLabel::QLabel(QWidget *, Qt::WindowFlags)' : Cannot convert parameter 1 from 'TestApp *const' to 'QWidget *' on the line
QLabel *processLabel=new QLabel(this);
Any ideas? Thanks!
EDIT: TestApp is a custom class.
If TestApp is a custom class, then it's perfectly normal that this code doesn't work.
Every UI element of Qt may take a parameter at construction, which is the QWidget that will act as a parent. This parent will notably have the responsibility for handling its children deletion. You should read more about this in the Qt Documentation (esp. the doc for QWidget constructor).
In your case, you shouldn't pass this to the QLabel constructor. You must pass another widget that'll become this QLabel parent.
The compiler shows clearly this problem with the message you got. It waits for a QWidget, but got your class instead (which doesn't inherit QWidget at any point).
Related
I'm trying to learn Qt and C++ and having some trouble understanding the C++ this keywork. I've seen examples where a class is derived from QMainWindow and then within the class member functions, a QMenu is added. One example is the "Simple menu" program described on this page:
http://www.zetcode.com/gui/qt4/menusandtoolbars/
In that example, a quit action is created with
QAction *quit = new QAction("&Quit", this);
However, imagine I want to also derive a class from QMenu and use that to create my menu.
mymenu.h
class MainWindow; // forward declaration
class MyMenu : QMenuBar
{
public:
MyMenu(MainWindow *main_window);
};
mymenu.cpp
#include "mymenu.hpp"
MyMenu::MyMenu(MainWindow *main_window) : QMenuBar()
{
QAction *quit = new QAction("&Quit", main_window); // Notice here I replaced
// 'this' with 'main_window'
QMenu = *file;
file = menuBar()->addMenu("&File");
file->addAction(quit);
connect(quit, SIGNAL(triggered()), qApp, SLOT(quit()));
}
Unfortunately this doesn't work because QAction expects a QObject as a parent. All that being said, there are a couple things that don't make sense to me:
If the class MainWindow inherits from QMainWindow, doesn't that make 'MainWindow' a QObject?
What is the difference between passing 'this' to QAction from within the class MainWindow, as opposed to passing 'main_window' which is (as far as I can tell) also a pointer to the instance from within the MyMenu class?
I apologize for such a long winded question, but if any of you have made it to the end with me, I would love any suggestions as to what I am missing here. The end goal here is just to create a derived class of QMenu (MyMenu here) and add it to the QMainWindow derived class (MainWindow here) existing in a separate class. Thank you for your time.
If the class MainWindow inherits from QMainWindow, doesn't that make 'MainWindow' a QObject?
Yes, MainWindow is a QMainWindow which is a QObject (you can see this by browsing the inheritance tree on the API docs).
You have only forward declared MainWindow. Since the compiler does not have a definition for the class MainWindow it can only do miminal things with a pointer to MainWindow. In order for the compiler to "know" that MainWindow is a QMainWindow which is a QObject, you must provide a class definition for MainWindow. You can solve your compiler error with:
#include "MainWindow.h"
No dynamic cast is needed
Also, in Qt land to make something "really" a QObject you should put the Q_OBJECT macro on the object:
class MyMenu : QMenuBar
{
Q_OBJECT
public:
MyMenu(MainWindow *main_window);
};
It might save you a few headaches later on if you ever plan to use the object for signal/slots or other Qt stuff.
What is the difference between passing 'this' to QAction from within the class MainWindow, as opposed to passing 'main_window' which
is (as far as I can tell) also a pointer to the instance from within
the MyMenu class?
this is a pointer to your custom MyMenu class which is also a QMenuBar. main_window is a pointer to your custom MainMenu class which is also a a QMainMenu. So, two different objects in memory. The second argument of the QAction constructor takes a pointer to a parent widget. The parent widget is responsible for managing the memory of its children. Since it takes a QObject its reasonable to pass in either this or main_menu.
Also you should probably pass a parent to the QMenu constructor.
MyMenu::MyMenu(MainWindow *main_window) : QMenuBar(main_window)
This way MyMenu is correctly deleted when the MainWindow is deleted.
The usual Qt paradigm is:
MyMenu::MyMenu(<arg1>, <arg2>, ... QObject * parent) : QMenuBar(parent)
But in this case forwarding along main_window is good enough.
I'm making a simple GUI with Qt Creator.
I'm trying to make an 'openFile' function in the mainwindow.cpp file, but I don't know whether to make this function a member of the mainwindow itself, a separate static function, or a member of a widget.
This function is simple really, it just calls a QFileDialog, gets the path to a file, and opens it, like every open file command on the menu bar you've ever seen.
Now here's the major problem I am having. I tried making this function a member of mainwindow so that I can access ui elements from within the function with ui->QTableWidget for instance, but I can't properly connect the signal to the slot if I do that. I get a whole slew of errors, because in order to do that I need a reference to the mainwindow since connect has the syntax connect(sender, signal, receiver, slot)
I then resorted to making the function separate on its own, but then it has no access to any of the ui elements.
How should I resolve this problem?
EDIT
Here is what I am doing in the constructor.
//Constructor
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QObject::connect(ui->actionOpen, &QAction::triggered, *parent, &MainWindow::openFile);
ui->tableWidget->setColumnCount(16);
}
Here is the resulting error:
C:\workspace\audioPipe\audioPipe\mainwindow.cpp:76: error: C2664: 'QMetaObject::Connection QObject::connect<void(__cdecl QAction::* )(bool),void(__cdecl MainWindow::* )(void)>(const QAction *,Func1,const MainWindow *,Func2,Qt::ConnectionType)' : cannot convert parameter 3 from 'QWidget' to 'const MainWindow *'
with
[
Func1=void (__cdecl QAction::* )(bool),
Func2=void (__cdecl MainWindow::* )(void)
]
No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
The compiler is telling you that as a third parameter to connect(), it expects a pointer to a MainWindow, i.e. a const MainWindow *. You however pass *parent, which is of type QWidget. Furthermore, parent is the wrong object anyway, since that is the parent of the MainWindow object, however you want to pass the MainWindow object itself - and that is this.
So something like the following should work:
QObject::connect(ui->actionOpen, &QAction::triggered, this, &MainWindow::openFile);
While it is possible to automatically remove a QGraphicsTextItem from a scene using a timer and Qt's signal-slot mechanism like
QTimer::singleShot(1000, QGraphicsTextItem*, SLOT(deleteLater()));
other graphical objects (QGraphicsItem, QGraphicsEllipseItem) seem to not inherit QObject and as such cause an error when compiling:
error: C2664: 'QTimer::singleShot': Konvertierung des Parameters 2 von
'QGraphicsEllipseItem *' in 'QObject *' nicht m”glich
(conversion / cast of parameter 2 ... not possible)
Since I would like text and some graphics shown together for a limited time, my question is:
How I can achieve automatic, timed removal of the above-mentioned 'other' objects?
QGraphicsItems don't inherit QObject normally. You would need to subclass QGraphicsEllipseItem like so:
class AutoHidingItem : public QObject, public QGraphicsEllipseItem
{
Q_OBJECT
// ...
}
Or you would simply have to have your scene keep track of the items to hide, and then hide it when it needs to. (Make a slot in your subclassed scene or view that hides or deletes the item.)
EDIT: #thuga pointed out that QGraphicsEllipseItem doesn't inherit QObject, while QGraphicsTextItem does already. Edited answer to show this.
Hope that helps.
How would I go about passing QSqlQueryModel from a class that connects and queries the database through the control class or QMainWindow in my attempt and back to the widget needing the information?
I thought I could pass the reference location to the QSqlQueryModel object, but this is not working or I am doing something wrong.
I haven't found any examples showing what I am doing on the Qt Developer page.
Looks like these are just compiler errors, nothing specifically to do with Qt.
In short you are getting your pointers and references mixed up.
Error #1:
cardList = new List(sqlModel->getListModel());
You are passing a reference when the List takes a pointer. Fix your return type from getListModel or fix the above line.
Next, you are not specifying the second argument, i.e. the parent QWidget. Either specify your MainWindow as the parent, pass 0, or fix your constructor's signature to provide a default (generally 0).
Error #2:
List::List(QSqlQueryModel *model, QWidget *parent) : ListUI(parent){
setListItems(&model);
}
You receive the model as a pointer and then attempted to take the address of the pointer. I.e. You're making a double pointer. Change the line to
setListItems(model);
Hope that helps.
I'm having a play around with Qt mainly looking to rewrite an old java app for symbian and I have got my self a bit confused.
I should first of all explain that C++ is not my kung-fu, and that may be the cause of the problem.
What I am trying to do is add a simple QPushButton to a Vertical Layout in a main window which has been built in qt designer at run time.
My example code is something like this...
QPushButton button = new QPushButton();
QString text("Testing Buttons");
button.setText(text);
//How do we add children to this widget??
ui->myLayout->addWidget(button);
The errors I am getting are as follows...
/home/graham/myFirstApp/mainwindow.cpp:22:
error: conversion from ‘QPushButton*’
to non-scalar type ‘QPushButton’
requested
/home/graham/myFirstApp/mainwindow.cpp:27:
error: no matching function for call
to
‘QVBoxLayout::addWidget(QPushButton&)’
/home/graham/myFirstApp/../qtsdk-2010.05/qt/include/QtGui/qboxlayout.h:85: candidates are: void
QBoxLayout::addWidget(QWidget*, int,
Qt::Alignment)
Now I know the first error has something to do with pointers but I don't know what, if anyone is able to clear up my confusion and provide example code that would be great.
Regards
Graham.
This is a merely C++ problem, you need to use asterisk to declare the button as pointer when you use new-operator.
QPushButton* button = new QPushButton();
button->setText(text);
ui->myLayout->addWidget(button);
QPushButton button = new QPushButton();
A pointer to QPushButton is not a QPushButton. That's what your compiler's bitching about and that's your problem.