I want to call a function indexChanged() if an index in my treeView is changed.
I used ui->treeView->currentChanged() signal but it didn't call indexChanged() slot, even though I connected the signal to the slot.
Here's my code :
.cpp file
TipManager::TipManager(QWidget *parent) :
QWidget(parent),
ui(new Ui::TipManager)
{
ui->setupUi(this);
connect(ui->treeView->selectionModel(), &QItemSelectionModel::currentChanged, this, &TipManager::indexChanged);
...
}
void TipManager::indexChanged(const QModelIndex ¤t, const QModelIndex &previous)
{
trimCurrentPath(previous);
}
.h file
namespace Ui {
class TipManager;
}
class TipManager : public QWidget
{
Q_OBJECT
public:
explicit TipManager(QWidget *parent = 0);
~TipManager();
public slots:
void indexChanged(const QModelIndex ¤t, const QModelIndex &previous);
private:
Ui::TipManager *ui;
...
};
I also tested in debug mode, but the slot function indexChanged() is not even called. Plus, it shows this message instead : QObject::connect: invalid null parameter
I hit a similar issue (the slot wasn't being triggered). Following #G.M.'s pointer in the comments to your question, it turned out that the call to ui->treeView->selectionModel() returns null if there's no model yet (and setSelectionModel() hasn't yet been called, presumably).
If I populated my QTreeView prior to calling ui->treeView->selectionModel() within the connect() call then I received my non-null response and the slot was triggered by the signal as desired.
Related
I'd like a signal to be connected to a slot inside of a struct. My struct looks like:
//Header file
struct someStruct {
public:
int index;
public slots:
void someSlot();
};
QList<someStruct*> mListOfStructs;
and then I create a button that should forward its clicked() signal to the someSlot function.
//Source file
QPushButton *cmd = new QPushButton();
grd->addWidget(cmd, 3, 2, Qt::AlignCenter);
//grd is a QGridLayout somewhere inside the gui. I can see it and also the button.
now connection the clicked() event with the slot inside a specific struct does not work.
connect(cmd, SIGNAL(clicked()), mListOfStructs[3], SLOT(someSlot()));
some sources tell me that I have to add a metaObject or sth. I tried but it didn't work out. Maybe you know better.
I might use How to connect in Qt signal and slot in dynamically added buttons to get in slot index of added button? as workaround though.
your structure need the Q_Object meta attributes in order to emit signals and recieve slot events...
struct testStruct : public QObject
{
Q_OBJECT
public:
int index;
testStruct():index(0){}
public slots:
void someSlot()
{
qDebug() << "slot called!";
}
};
after that you can conected as usual:
testStruct *ts= new testStruct;
connect(this, SIGNAL(someSignal()), ts, SLOT(someSlot()));
I was following some code posted in other questions on how to connect the status bar between parent and distant child by means of signals and slots.
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent)
{
...
connect(myCanvas,SIGNAL(mouseMoved(QString)),
this,slot(setStatusBar(QString)));
...
}
Somewhere in the class MainWindow the following is declared as public slot:
void MainWindow::setStatusBarText(const QString& text) {
statusBar()->showMessage(text);
}
in the class to which myCanvas belongs declares the signal:
signals:
void mouseMoved(const QString&);
And emits the signal:
void GraphicsView::mouseMoveEvent(QMouseEvent *mouseEvent)
{
...
emit mouseMoved(QString("("+QString::number(mouseMoveCatch.x())+";"
+QString::number(mouseMoveCatch.y())+")"));
...
}
I am sure QString is properly included. But when i compile I get an error on the connect line saying "QString does not refer to a value".
I have no clue what this means. Thanks for any help!
You have a case error on the line
connect(myCanvas,SIGNAL(mouseMoved(QString)),
this,slot(setStatusBar(QString)));
You should be using SLOT, not slot.
The application I am writting as unique instantiation of some classes which have to be accessible easily. For that i use singletons.
For exemple my Core is defined as :
class Core : public QObject
{
Q_OBJECT
public:
Core();
~Core();
static Core& getCore()
{
static Core mycore;
return mycore;
}
(...)
};
and it works just great. However I tried to do the same with my MainWindow class, which interits from QMainWindow. I need that in order to access methods such as geometry() from other objects
However Core works great, MainWindow makes error when clossing the programe. The main window destructor is called and executed apparently once ( debug using qDebug() ) but i still have a SIGSEGV signal. What's happening? How to solve it?
Here is the code of MainWindow
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
~MainWindow();
static MainWindow& getUi()
{
static MainWindow myUi;
return myUi;
}
public slots:
void refreshImage();
private:
Ui::MainWindow *ui;
};
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect(&appCore(), SIGNAL(refreshed()), this, SLOT(refreshImage()));
}
MainWindow::~MainWindow()
{
delete ui;
}
And the main code
QApplication app(argc, argv);
try
{
appCore().setDevice(MDMA::Kinect);
appUi().show();
return app.exec();
} catch(MDMA::exn e) {
(...)
}
where appCore and appUi are macros for Core::getCore and MainWindow::getUi()
This crash probably results from your QApplication being destroyed before the MainWindow.
If you cannot pass your MainWindow via other ways to the code where it is needed (e.g. as argument or via QObjecg::parent()), you could employ a technique similar to what QApplication does with it's instance method (a non-owning global reference):
Construct your MainWindow as an ordinary local variable on the stack, after the QApplication. Then set a global pointer (maybe better a QPointer; e.g. a static member of MainWindow), which you initially initialize to 0, to this in the constructor of MainWindow. You can also check if it was already initialized here to enforce the uniqueness. Via a public accessor method (instance?) for the global pointer, you can access the class from everywhere while ensuring destruction before QApplication.
If you want to make singletone, try to use general technics, for example, as described here:
http://www.qtcentre.org/wiki/index.php?title=Singleton_pattern
Hope, lot of questions will dissappear after reading all of that article.
As for me, there is nice and simple realization of singletone.
Good luck!
I'm trying to use a QAction (QMenu member entry) to open a new window. Precisely: I want actionAbout signal predefined activated to match MainWindow custom slot open AboutWindow - and that's what I've got trouble with.
I know that I can use either the connect Qt function manually inside the source main_window.cpp file or just click it up in the Qt Creator, but my custom slot doesn't show up so I cannot select it. Maybe my slot function declaration is wrong (invalid parameters) and that's why QtCreator doesn't allow me to choose my custom slot in the GUI signals & slots. Could anyone point me what should I do to make QtCreator display my custom slot in the dropdown and how should the connect function call look like?
This is my main_window.h file content:
#include
#include "about_window.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
public slots:
void openAboutWindow();
private:
Ui::MainWindow *ui;
Ui::AboutWindow *aboutWindow;
};
And this is main_window.cpp:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect(actionAbout, SIGNAL(activated()), this, SLOT(openAboutWindow(this));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::openAboutWindow(QWidget *parent)
{
aboutWindow = new Ui::AboutWindow(parent); // Be sure to destroy you window somewhere
aboutWindow->show();
}
The compiler shouts about both constructor and openAbutWindow:
../Application/main_window.cpp: In constructor ‘MainWindow::MainWindow(QWidget*)’:
../Application/main_window.cpp:9:13: error: ‘actionAbout’ was not declared in this scope
../Application/main_window.cpp:9:80: error: expected ‘)’ before ‘;’ token
../Application/main_window.cpp: In member function ‘void MainWindow::openAboutWindow(QWidget*)’:
../Application/main_window.cpp:19:44: error: invalid use of incomplete type ‘struct Ui::AboutWindow’
../Application/about_window.h:7:11: error: forward declaration of ‘struct Ui::AboutWindow’
../Application/main_window.cpp:20:15: error: invalid use of incomplete type ‘struct Ui::AboutWindow’
../Application/about_window.h:7:11: error: forward declaration of ‘struct Ui::AboutWindow’
../Application/main_window.cpp:9:13: error: ‘actionAbout’ was not declared in this scope
The error message says it all, where is the QAction defined? Should it be ui->actionAbout?
connect(actionAbout, SIGNAL(activated()), this, SLOT(openAboutWindow(this));
openAboutWindow() does not take any arguments, and regardless this is an instance not a type.
In main class MainWindow I have method which sets setEnabled("false") for each button, when the application is downloading. In other class "Download" I have method responsible for downloading. There is sth like this if ( uRet == S_OK ) and after download I would like to setEnable("true") for each button, but I can't run method from MainWindow in this if() 'couse I get "QWidget: Must construct a QApplication before a QPaintDevice".
How to run the method from the MainWindow class in the Download Class, or refer to these buttons from the Download Class.
edit:// I need to emit signal
class downloaded : public QObject
{
Q_OBJECT
public:
void test3();
signals:
void changeEnabled();
};
void downloaded::test3(){
emit changeEnabled();
}
class MainWindow : public QMainWindow{
Q_OBJECT
public:
...
public slots:
void ONchangeEnabled();
}
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
downloaded test_object;
connect(&test_object, SIGNAL(changeEnabled() ), this, SLOT(ONchangeEnabled() ) );
ui->setupUi(this);
setupUI();
}
void MainWindow::ONchangeEnabled(){
ui->actionDL->setEnabled(true);
}
and in function which downloads files I have sth like that.
downloaded obiekt;
...
if ( uRet == S_OK )
{
obiekt.test3(); return 0;
}
else {
obiekt.test3(); return 1;
}
But nothing happens, what am I doing wrong.
Signals are always object and not class level. You are not connecting to the instance of "downloaded" object you are trying to listen signals to. The one you connect to is created and deleted in the MainWindow constructor, and has no relevance to the one created in the second code block.