Automatic indentation in VS editor obviously does not know about Qt. And declarations of signals and slots are auto-formatted like this:
class MyClass : public QObject
{
Q_OBJECT
public:
MyClass();
signals: // <-- Broken indentation
void someSignal();
public slots: // <-- Also broken
void someSlot();
};
I want "signals:" and "slots:" automatically formatted just like access specifiers. What are the options? (I'm using VS2010)
In short answer seems to be NO. Maybe not what you are looking for but maybe you can live with this:
class MyClass : public QObject
{
Q_OBJECT
public:
MyClass();
private:
Q_SIGNAL void someSignal();
public:
Q_SLOT void someSlot();
};
(It's ugly but it seems you can't have your cake and eat it too ;)
Just something I'm wondering about: Is it worth the effort to build a plugin for automatic formatting? Do we really use CTRL-A CTRL-F so much? If so, then yes it could be a pain. But normally if you are working on header files declaring a new method (signal or slot) should not mess up the previous corrected indentation. Perhaps you have some reasons that justifies this?
Related
I am not able to understand the usage of Q_PROPERTY. How th Q_PROPERTY helps in making a program defensive? What is it used for? I have seen the forum, but really not able to make its applicaton. I have understood the example, but not it's usage.
Here is the example, what do I gain with it. I understand that read will give a privilege of reading only.
The write property will give the privilege to write only. But what is the need of it? Can someone exemplify it?
class MyClass : public QObject
{
Q_OBJECT
Q_PROPERTY(Priority priority READ priority WRITE setPriority NOTIFY priorityChanged)
Q_ENUMS(Priority)
public:
MyClass(QObject *parent = 0);
~MyClass();
enum Priority { High, Low, VeryHigh, VeryLow };
void setPriority(Priority priority)
{
m_priority = priority;
emit priorityChanged(priority);
}
Priority priority() const
{ return m_priority; }
signals:
void priorityChanged(Priority);
private:
Priority m_priority;
};
It has the following advantages:
It is available for the meta object system, so it can be introspected, used from QML etc.
It has further options than just read and write. Look at notify, reset, etc. It is also easier to integrate them into QtCreator (designer).
You do not need to write the boilerplate with Qt 5.1 onwards in common read and write cases because they will be generated for you.
Im implementing a new slot which just has to call the method reset(). My new class is subclassing QAbstractListModel in which QAbstractListModel::reset() exists.
//stationlist.h
class StationListModel : public QAbstractListModel
{
Q_OBJECT
...
public slots:
void dataChanged();
//stationlist.cpp
...
void StationListModel::dataChanged()
{
reset();
}
However, in the implementation the method reset() is recognized as QTextStream::reset() and doesn't compile because of this. What could be the cause for such behaviour?
Thanks to the comment, the conclusion is that the method QAbstractListModel::reset() doesn't exist.
It is here only still available fer backwards compatibility http://qt-project.org/doc/qt-5.1/qtcore/qabstractitemmodel-compat.html#reset.
I believe that QTextStream::reset() is just something that the QtCreator offered as a global autocomplete.
The solution is to use non deprecated method.
in python we write custom slots quite easily by passing in the function to be called when a signal is generated.
While in C++ connect function requires us to pass the address of the slot function or so i figured. How do i do that. I tried using this but did'nt work.
Python code::
class imviu(QtGui.QWidget):
def __init__(self):
super(imvui,self).__init__()
self.btn=QtGui.QPushButton('Browse')
btn.clicked.connect(self.openimg)
def openimg(self):
#do something
C++ code::
class imviu: public QWidget
{
public:
imviu(QWidget *parent=0);
QPushButton *btn=new QPushButton("Browse");
void openimg(void);
};
imviu::imviu(QWidget *parent)
:QWidget(parent)
{
connect(btn, SIGNAL(clicked()),this,SLOT(openimg()));//this does'nt work:QObject::connect: No such slot QWidget::openimg()
}
void imviu::openimg()
{
//do something
}
In order to use signals and slots, you need to have the Q_OBJECT macro in your class as well as identifying which functions should be the signals and the slots. Have a look at the documentation for a more in-depth explanation.
After this, you need to set up the project file so that MOC can generate the necessary code.
Your class definition should look like this:
class imviu: public QWidget
{
Q_OBJECT
public:
imviu(QWidget *parent=0);
public slots:
void openimg();
private:
QPushButton *btn;
};
Using Qt's signal & slot, I get error:
Object::connect: No such signal FvOverlayPolygon::mouseHoveredOnElemSig(rf::AbstractFvOverlay*)
My other connects work fine and I've checked everything I can think of (refered to 20 ways to debug Qt signals and slots too). Because I personally for the first time use shared_ptr for Qt for this sample, I suspect there might be something wrong in how I use shared_ptr. I really appreciate your opinions.
concreteFvOverlay.cpp
#include "rf_common/abstractFvOverlay.h"
void FvScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent)
{
rf::AbstractFvOverlay::Ptr item_overlay;
item_overlay = this->createOverlay(myItemMenu, &pixmap_overlay); // this inherits Class A
bool con1 = connect(item_overlay.get(), SIGNAL(mouseHoveredOnElemSig(rf::AbstractFvOverlay*)), this, SLOT(mouseHoveredOnElem(rf::AbstractFvOverlay*)));
}
}
This overlay is instantiated in this:
abstractFvOverlay.cpp
boost::shared_ptr<rf::AbstractFvOverlay> FvPolygonScene::createOverlay(QMenu *menu, QPixmap *pixmap_overlay)
{
return boost::shared_ptr<rf::AbstractFvOverlay>(new FvOverlayPolygon(menu, *pixmap_overlay));
}
overlay.h
#include <QGraphicsItem>
#include <boost/shared_ptr.hpp>
class AbstractFvOverlay : public QObject, public QGraphicsItem
{
Q_OBJECT
public:
AbstractFvOverlay(QMenu *contextMenu, QGraphicsItem *parent, QGraphicsScene *scene);
virtual ~AbstractFvOverlay();
typedef boost::shared_ptr<AbstractFvOverlay> Ptr;
signals:
void mouseHoveredOnElemSig(AbstractFvOverlay *i);
For your interest, the reason I use shared_ptr here is I want to do interface-based programming (not sure if this is an official way to call this style but what I mean is defining behavior in abstract classes and only for some behaviors I describe them in concrete classes, which Java allow).
You must use full scope names of types in signal declaration even if you're in same scope. Replace signal void mouseHoveredOnElemSig(AbstractFvOverlay *i); with void mouseHoveredOnElemSig(rf::AbstractFvOverlay *i); or use AbstractFvOverlay without scope in your connect.
I'm developing a project, and I first began making it without GUI, but now I'm porting it to Qt, but I have a problem.
I have my "old" implementation in a separate file, and I try to access the MainWindow widget from it, in order to output to a QTextBrowser, but I'm not able to do so.
In mainwindow.cpp I have this:
void MainWindow::addString(char* text)
{
std::string input = text;
ui->textBrowser->append(QString::fromStdString(input));
return;
}
In mainwindow.h:
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_showWelcome_triggered();
void on_showArithmetic_triggered();
private:
Ui::MainWindow *ui;
public slots:
void btnResolveClicked();
void btnClearClicked();
void hideAll();
void addString(char* output);
};
#endif // MAINWINDOW_H
And in simple_mode.cpp:
void test()
{
MainWindow *gui = new MainWindow;
gui->addString("WORKS");
MainWindow:: = gui;
}
However this doesnt append "WORKS" to the textbrowser, which is what I need, I think it adds it to another instance of text browser which isnt the same as the mainwindow.
EDIT:
What I wanted to do was appending a line of text directly from simple_mode.cpp to the textbrowser.
By the way, simple_mode was written without any Qt aid, that's why I used std strings, and currently the textbrowser widget acts as a virtual terminal output screen, and instead of using printf like I did before, I wanted to append lines to the textbrowser. However I already found my way through, I don't need this now.
I needed help
It's really hard to tell what do you want to achieve and pieces of code do not cover all possible erroneous areas (i.e. where's the MainWindow constructor's definition?). Also, the formatting is terrible - please use idents and consistent bracing style.
My advice is simply call show on MainWindow instance. Unless you don't mess up ui initialization in MainWindow constructor, this snippet should be enough. If it is not - supply us with missing pieces of code.
void test()
{
MainWindow *gui = new MainWindow;
gui->addString("WORKS");
gui->show();
}
As a side note, your addString method should look like this:
void MainWindow::addString(char* text)
{
ui->textBrowser->append(QString::fromAscii(text));
}
Return statement is completely unnecessary, and assigning text to std::string is likely to cause unnecessary memory allocation. It's not like it is the end of the world, but it's really, really bad practice for a C++ programmer.