KeyPressedEvent not registering - c++

I am new to Qt and trying to implement what should be a pretty straightforward "key pressed" event method, but it doesn't seem to be registering properly.
Here is the declaration in my header file:
#include <Qt>
#include <QKeyEvent>
class MainWindow : public QMainWindow
{
Q_OBJECT
protected:
void KeyPressEvent(QKeyEvent* event);
};
and here is the implementation:
void MainWindow::KeyPressEvent(QKeyEvent *event)
{
qDebug() << "Registered Key Press";
}
This is almost exactly what the examples I have seen online look like, so unless there is some connection somewhere I am missing, not sure what the issue would be.

It is, as you say, almost exactly what the examples show. They should show
void keyPressEvent(QKeyEvent* event) override;
See QWidget::keyPressEvent. Note that C++ is case sensitive (K -> k).
Also, I've added the override keyword - then the compiler will tell you if you try to override a function which the compiler doesn't know!
Additional caveats are included in above linked documentation:
Make sure to call setFocusPolicy with an appropriate policy;
Note also that child widgets can "swallow" events. Meaning that if your main window has any children; and the key press happens inside a child, the child can say "I handle this event, no need to pass it on to my parent". Then your MainWindow::keyPressEvent also won't get called; see the corresponding notes in the QKeyEvent documentation; the gist: any child window of your MainWindow handling keyPressEvent has to ignore() the event in order for it to propagate to the parent class.

Related

Qt slot and signal: no matching function in MainWindow

I have looked at a variety of the Qt discussions for this error "no matching function for call to" and I still cannot see what is different in this case. I have successfully set up slot/signal pairs between GUI elements, but for some reason the latest set of slot/signal pairs is creating an error.
In order to allow all GUI elements to update the status bar on the main window I have created a signal in each panel as shown here
class PanelA : public QWidget
{
...
public signals:
void UpdateStatusBar(std::string);
...
}
Then in MainWindow there is a slot
//from MainWindow.h
class MainWindow : public QMainWindow
{
private slots:
void ReceiveStatus(std::string);
}
//from MainWindow.cpp
void MainWindow::ReceiveStatus(std::string s)
{
//I can provide other controls, filters, etc.
//but currently there are none
ui->statusBar->showMessage(tr("System status: "+s));
}
And finally, in the MainWindow constructor I have several signals already and I have added one new connect line for each GUI element.
connect(ui->panelA, &PanelA::SelectionChanged, ui->panelB, &PanelB::UpdateSelection);
//this one works
connect(ui->panelA, &PanelA::UpdateStatusBar, ui, &MainWindow::ReceiveStatus);
//this one generates an error there is one status bar connection for each
So, as far as I can tell the syntax is right. both ui->panelA and ui are pointers. I don't know why one is correct and the other is wrong. I'd appreciate any suggestions.
Probably should be:
connect(ui->panelA, &PanelA::UpdateStatusBar, this, &MainWindow::ReceiveStatus);
The ui object isn't a MainWindow, but this will be.

hide QWidget from a different QWidget

I have a MainWindow with two widgets, buttonsWidget and infoWidget.
I'm trying to to hide infoWidget after clicking a button within buttonsWidget (and ultimately show a different widget).
I've tried:
mainwindow.h
public:
void hideInfo();
mainwindow.cpp
void MainWindow::hideInfo()
{
ui->info->hide();
}
buttonsWidget.cpp
void buttonsWidget::on_timingButton_clicked()
{
MainWindow::hideInfo();
//Then will do something to show 'timingWidget'..
}
Many thanks
You should use Signals and Slots for this.
Add a signal in the buttonsWidget.h.
signals:
void hideInfoSignal();
In the main function, connect the button signal with the mainwindow method hideInfo().
QObject::connect(this->info, SIGNAL(hideInfoSignal),this, SLOT(hideInfo));
I haven't tested this, because I dont have Qt on this machine, but that should work, with possible minor modifications. If any errors appear, let me know and I will help. Also, read the signals and slots documentation.

QObject::sender() doesn't work properly in a slot

I want to make a button to stay pushed after a click. So I made a slot make_pushed which I try to use for that purpose. The button which was clicked on is identified by QObject::sender() method. But something goes wrong since it doesn't work.
QPushButton * size=new QPushButton("size",this);
connect(size, SIGNAL(clicked()), this, SLOT(make_pushed()));
void Window4::make_pushed()
{
QObject* sender = this->sender();
QPushButton* button = qobject_cast<QPushButton*>(sender);
button->setDown(true);
button->setText("Yep");
}
class Window4 : public QWidget
{
public:
Window4(QWidget * parent=0);
private slots:
void make_pushed();
};
There's a mistake in application output "QObject::connect: No such slot QWidget::make_pushed() in" , although everything compiles and the window appears. The problem is the slot is apparently not found, although it is in the same cpp file and in the header. And therefore when clicked, the botton neigher changes its text nor stays pushed.
You just forgot Q_OBJECT macro in class declaration http://doc.qt.io/qt-5/qobject.html:
Notice that the Q_OBJECT macro is mandatory for any object that implements signals, slots or properties. You also need to run the Meta Object Compiler on the source file. We strongly recommend the use of this macro in all subclasses of QObject regardless of whether or not they actually use signals, slots and properties, since failure to do so may lead certain functions to exhibit strange behavior.
http://doc.qt.io/qt-5/qobject.html#Q_OBJECT:
The Q_OBJECT macro must appear in the private section of a class definition that declares its own signals and slots or that uses other services provided by Qt's meta-object system.
Note: This macro requires the class to be a subclass of QObject. Use Q_GADGET instead of Q_OBJECT to enable the meta object system's support for enums in a class that is not a QObject subclass.
Just use it like this every time you subclass QObject/QWidget/...:
#include <QObject>
class Counter : public QObject
{
Q_OBJECT
// ...
}

Qt Minimized Taskbar Icon Mouse Event

I've tried virtually every way possible to hook the activated() signal of a taskbar icon to a corresponding slot. However, I do not understand why Qt(Qt5 Cretor) says I don't have a matching function for the slot.
Qt Error:
C:\Users\potato\Desktop\CCT-master\CCTracker\cctsystemtray.cpp:40:
error: no matching function for call to
'QObject::connect(QSystemTrayIcon*&, const char*, CCTSystemTray*
const, const char*)'this,
SLOT(systrayActivated(QSystemTrayIcon::ActivationReason)))
As far as I can tell, according to Qt Documentation,
The activated() signal is used to catch mouse events such as clicks and double clicks for the taskbar icon. At first try I thought it's only signals and slots, but then for whatever reason activated() just won't fit. And If I try connecting activated() to a slot from another class, everything fails due to pointer errors.
Here's are the working parts inside CCTSystemTray.h:
class CCTSystemTray
{
public:
CCTSystemTray();
void initSystemTray(QWidget *rootWindow);
private:
QSystemTrayIcon* systray;
public slots:
void systrayActivated(QSystemTrayIcon::ActivationReason);
};
And CCTSystemTray.cpp:
// Above are Class declearations, menu items, etc...
QObject::connect(this->systray, SIGNAL(QSystemTrayIcon::activated(QSystemTrayIcon::ActivationReason reason)),
this, SLOT(systrayActivated(QSystemTrayIcon::ActivationReason)));
}
void CCTSystemTray::systrayActivated(QSystemTrayIcon::ActivationReason)
{
qDebug() << "Hello";
}
The full code sample can be found here on pastebin.
If someone can help me out from hair-pulling, that'd be great!
Thank you all.
Your class CCTSystemTray has a slot, but it is not a QObject (it doesn't derive from QObject or another class derived from QObject) and also you need the Q_OBJECT macro in your class declaration and then signals and slots will work.

can't connect QT signal

i am new to QT and was trying to create a custom signal that would tell me a removable disk has been inserted.
This is what i did
MainWindow.h
class MainWindow
{
QOBJECT
..
..
signals:
void qm_diskInserted(QString &);
public slots:
void addItemToList(QString &);
...
}
MainWindow.cpp
void MainWindow::onDeviceChange(MSG * msg)
{
//code for detecting device here
QString &driveLetter= getDriveLetter(mask);
//try to emit QT signal here
emit qm_diskInserted(driveLetter);
}
MainWindow::MainWindow(QWidget * parent=NULL)
{
ui.setupUi(this);
QObject::connect(this, SIGNAL(qm_diskInserted(QString&)), this, SLOT(addItemToList(QString &));
}
void MainWindow::addItemToList(QString &)
{
//more stuff here
}
somehow the slot addItemToList() isn't called and i have to call it manually.
What am i doing wrong?
Thanks.
PS:
By the way is there any way of debugging signals?
Ie how can i be sure that a signal is emitted?
It is at least supposed to be Q_OBJECT. I think you also need to inherit QMainWindow.
This is a long shot, but are you sure onDeviceChange() method is called?
EDIT
Classes which have Q_OBJECT macro in their body needs to inherit directly or indirectly from QObject, and in your code it is not the case.
With connection problems, always make sure that you check the console for messages about connect failures. Since Qt can't tell if a connection makes sense until runtime, it notifies you of failures there. You'd think it would crash, but it just quietly says these things in the console.
With Qt, it makes sense to watch the console always. Qt prints out all sorts of error messages that can help when you've got a problem.
Try making your signals virtual void instead and make sure that your MainWindow class inherits (directly or indirectly) from QObject
EDIT
As mentioned in other comments, the macro should be Q_OBJECT