I need to handle an event that is fired after widget is fully visible like after show event. But I cannot find any event like that in Qt4. I already tried the solutions suggested below. But none of them worked.
My aim: I am working on an embedded system and I am using Qt for UI. What I am trying to do is to show hardware accelerated camera on UI after CustomWidget is shown. If I use showEvent, camera is shown before CustomWidget is fully drawn.
It seems that showEvent is fired before widget is fully drawn. It behaves like before show event.
Failure-1
bool CustomWidget::event(QEvent *event)
{
bool returnValue = QWidget::event(event);
if (event->type() == QEvent::Polish)
{
this->camera->show();
}
return returnValue;
}
Polish event is called once. When I hide and show the widget again and again, it never fired.
Failure-2
void CustomWidget::showEvent(QShowEvent *event)
{
QWidget::showEvent(event);
QTimer::singleShot(0, this, SLOT(dialogExec));
}
void CustomWidget::dialogExec()
{
this->camera->show();
}
This did not work either.
Failure-3
void CustomWidget::paintEvent( QPaintEvent *event )
{
QWidget::paintEvent( event );
if( !this->camera->isVisible() )
{
this->camera->show();
}
}
void CustomWidget::hideEvent( QHideEvent *event )
{
this->camera->hide();
}
QWidget has protected members called closeEvent( QCloseEvent* event ) and showEvent( QShowEvent* event ). Maybe you can use these methods to manage the camera.
Related
I am hiding a Qt toolbox window in one of my functions. I need to do some screen capturing stuffs to be executed in function after hiding my toolbox window.
void ProcessData()
{
Toolbox::getInstance()->hide(); //I am trying to hide toolbox here
//screen capture stuffs. - It should be executed once the toolbox window is hidden.
}
But what happens is, Toolbox is hidden only when the ProcessData() returns. This leads to the problem that my captured screen have the toolbox.
Is there any way to wait for the toolbox to be hidden in Qt ?
Apart from using QApplication::processEvents, I would suggest you a more elegant solution:
Reimplement QWidget::hideEvent of the class returned by Toolbox::getInstance to emit a signal, e.g. widgetHidden
protected:
void hideEvent(QHideEvent *event) {
QWidget::hideEvent(event);
Q_EMIT widgetHidden();
}
signals:
void widgetHidden();
Connect widgetHidden to a slot to capture the screen
connect(Toolbox::getInstance(), &MyWidget::widgetHidden, this, &ClassName::onWidgetHidden);
where MyWidget is the class returned by Toolbox::getInstance and ClassName is the name of the class to which ProcessData belongs.
Add a flag to know if it is the right time to capture, as the widget might be hidden in some other way
bool m_captureAllowed = false;
Implement the onWidgetHidden slot
private slots:
void onWidgetHidden() {
if (m_captureAllowed) {
m_captureAllowed = false;
//screen capture stuffs
}
}
Set the flag in ProcessData
void ProcessData()
{
m_captureAllowed = true;
Toolbox::getInstance()->hide(); //I am trying to hide toolbox here
}
I wanted to do some action when a dialog shows when it opens or when it maximizes from a minimal status or it moves from out of a screen.
Does QT have such a signal?
I am also not sure where to find if QT has a list of signals defined.
Does each QT widget have a 'show' signal?
If you look at Qt source code then you will find QWidget::show to be a slot:
public Q_SLOTS:
// Widget management functions
virtual void setVisible(bool visible);
void setHidden(bool hidden);
void show();
The slot is mainly for us, programmers to make us able to connect with signals for specific purposes like clicking the button we created does something to certain widget. As for Windows or Mac OS, we have the app serving all the events coming from the system via event loop. And QWidget reacts on all the 'signals' in the form of system events coming and yes, may, execute show() or showMaximized() or showMinimized slots then.
But I can assume you want to overload
virtual void showEvent(QShowEvent *);
virtual void hideEvent(QHideEvent *);
Like:
void MyWidget::showEvent(QShowEvent *e)
{
if (isMaximized())
{
if (e->spontaneous())
{
// the author would like to know
// if the event is issued by the system
}
; // the action for maximized
}
else
{
; // the action for normal show
}
}
void MyWidget::hideEvent(QHideEvent *)
{
if (isMinimized())
{
; // the action for minimized
}
else
{
; // the action for hide
}
}
For recognizing cases when the system operates the widget we can use QEvent::spontaneous().
Please also refer to show and hide event doc pages:
http://doc.qt.io/qt-5/qshowevent-members.html
http://doc.qt.io/qt-5/qhideevent.html
I catch the mouseMoveEvent of my QWebView for restarting a timer of a screensaver. The problem is that now the mouseMoveEvent isnt distribued to the HTML elements so its impossible for example to move a sliding bar on the page.
I use connect to bind mouseMoveEvent to the restart slot :
QObject::connect(_view, SIGNAL(mouseMoveEvent(QMouseEvent*)), _mediaPlayer, SLOT(stop()));
WebView class :
class WebView : public QWebView
{
Q_OBJECT
public:
WebView(QString menu) : _menuDesc(menu) {};
WebView(){};
void setMenuDesc(QString menu) {_menuDesc = menu;};
QString getMenuDesc() {return _menuDesc;};
void setCurrPage(QString page) {_currPage = page;};
QString getCurrPage() {return _currPage;};
void setCurrCategory(QString page) {_currPage = page;};
QString getCurrCategory() {return _currPage;};
void mouseMoveEvent(QMouseEvent *)
{
emit mouseMoved();
};
signals :
void mouseMoved();
private:
QString _menuDesc = 0;
QString _currPage;
QString _currCategory = 0;
};
Is there a solution to still catch the signal and pass it to the HTML page?
mouseMoveEvent is not a signal but an event handler. You can reimplement this event handler and let it emit a signal you can connect to if you need that.
Like this:
MyWebView::mouseMoveEvent(QMouseEvent * e) {
emit mouseMoved(); // this would be signal you could connect to.
}
Seems you misunderstand event handler and signal usages.
mouseMoveEvent is a member method of QWidget, is not a signal so you cannot connect to it. You can override it in you subclass and emit your own signal.
And if a QWidget's mouse tracking is switched off, mouse move events only occur if a mouse button is pressed while the mouse is being moved. Maybe you need to call setMouseTracking too.
I have a Qt/cpp code and display a subclassed QLineEdit. When double-clicking the QLineEdit, the focusInEvent is never called (launched in Maya).
void myQLineEditClass::focusInEvent(QFocusEvent *e)
{
MGlobal::displayInfo(MQtUtil::toMString(QString().sprintf("HERE")));
QLineEdit::focusInEvent(e);
}
HERE is never displayed, event if the focusInEvent is present in the .h protect part. Any idea how to get focusInEvents ?
Try the below. For several occasions that worked for me when focusInEvent did not.
void YourWidget::changeEvent(QEvent* event)
{
if (event->type() == QEvent::ActivationChange)
{
if (isActiveWindow())
{
// gaining the focus
}
else
{
// loosing the focus
}
}
// or whatever *parent* class call is
QWidget::changeEvent(event);
}
The event gets intercepted by the editor widget. See QItemDelegate::createEditor. The widget returned there will get it.
The issue was linked to the fact that the QLineEdit was in a QGraphicsView that was in another QGraphicsView. Bringing the QLineEdit to the higher-level QGraphicsView made it work.
I have a Qt application with multiple widgets showing buttons at the same time. In certain circumstances, I want key presses to be sent to one of the widgets, even if that widget doesn't have focus. To do this, I have overridden keyPressEvent() in the master widget (that owns all subwidgets in this application) and re-send the key event to the subwidget if it doesn't have focus using code similar to this:
if (!someWidget->hasFocus())
{
QApplication::sendEvent(someWidget, keyEvent);
}
This works great as long as someWidget handes said event. If it ignores it, then it enters a nasty infinite recursive loop since events flow up to parents.
Is there a way to know where an event came from so I can prevent this infinite loop? I'm thinking of something like this:
if (!someWidget->hasFocus() && (keyEvent->source != someWidget))
{
QApplication::sendEvent(someWidget, keyEvent);
}
Or is there a different way I can prevent this from happening?
When you use signals and slots mechanism you can call sender() which can give you information, but here you can do next: use eventFilter which can give you information about every QObject which sends events to mainWindow, so you can catch event and sender
bool MainWindow::eventFilter(QObject *obj, QEvent *event)
{
if(event->type() == QEvent::KeyPress)//your keyPressEvent but with eventFilter
if(!someWidget->hasFocus() && obj != someWidget)//your focus and source checkings, obj is object which send some event,
// but eventFilter catch it and you can do something with this info
{
//do something, post event
}
return QObject::eventFilter(obj, event);
}
Don't forget
protected:
bool eventFilter(QObject *obj, QEvent *event);
Maybe you need use QKeyEvent, so cast QEvent if you sure that event->type() == QEvent::KeyPress. For example:
QKeyEvent *key = static_cast<QKeyEvent*>(event);
if(key->key() == Qt::Key_0)
{
//do something
}