QT window ActivationChange event under linux - qt

I have the following issue: I have a "splash" like window coming with my application and it has a few buttons on it for opening the last project, creating a new one, etc... On pressing, these buttons hide the window and do the stuff.
This window is created with the following code and flags:
void MainWindowButtonDialog::showMe()
{
setModal(false);
setWindowFlags(Qt::SplashScreen | Qt::CustomizeWindowHint |
Qt::WindowStaysOnTopHint | Qt::X11BypassWindowManagerHint);
show();
}
The window is called m_btnDlg.
Now, due to requests from the clients when the application loses focus I need to hide this window, and when the application gets focus I need to re-show it. This is done by the following code:
void MainWindow::changeEvent(QEvent *e)
{
if( e->type() == QEvent::WindowStateChange )
{
if( isMinimized() )
{
if(m_btndlg && m_btndlg->isVisible())
{
m_btndlg->hide();
m_splashWasVisible = true;
}
}
else
{
if(m_splashWasVisible)
{
m_btndlg->show();
m_splashWasVisible = false;
}
}
}
if(e->type() == QEvent::ActivationChange)
{
if(!isActiveWindow())
{
if(m_btndlg && m_btndlg->isVisible() && !m_btndlg->isActiveWindow())
{
m_btndlg->hide(); // *****
m_splashWasVisible = true;
}
}
else
{
if(m_splashWasVisible)
{
m_btndlg->show();
m_splashWasVisible = false;
}
}
}
QMainWindow::changeEvent(e);
}
Now to the problem: the code above worked perfectly till now (both under Linux - Gnome 2.x on CentOS 5.x, and KDE 3.x and also Windows, all interesting versions). Recently the client has installed a few Fedora systems and Gnome 3, KDE 4, etc... suddenly the application behaves funnily. When I press the the button to create a new project it hides the splash window and nothing happens. The line marked with ** above is the one responsible. It seems that these new window managers send the activation events out of order.
Has anyone experience with this?
(More Code available on request). We use Qt 4.6.3
thanks.

You should try the application level events QEvent::ApplicationActivate and QEvent::ApplicationDeactivate with an event filter installed on qApp.
These events are fired when the application focus changes or the application window is minimized.
MainWindow::MainWindow() {
qApp->installEventFilter(this);
}
bool MainWindow::eventFilter(QObject *obj, QEvent *evt)
{
if(obj==qApp && ( evt->type() == QEvent::ApplicationActivate
|| evt->type() == QEvent::ApplicationDeactivate))
{
bool shouldHide = evt->type() == QEvent::ApplicationDeactivate;
if (shouldHide) {
m_splashWasVisible = m_btndlg && m_btndlg->isVisible();
if(m_splashWasVisible)
m_btndlg->hide();
} else {
if(m_splashWasVisible)
m_btndlg->show();
}
}
return QMainWindow::eventFilter(obj, evt);
}
Alternatively, you could display the splash window as part of the main window on top of all other widgets by setting the main window as its parent, and using QWidget::raise().

Related

How can I check a WheelEvent is from mouse wheel or touchpad in qml on Windows?

I tried this var isTrackPad = wheel.pixelDelta !== Qt.point(0,0); as this says.
But it seems pixelDelta works only on Mac. Is there other method to check if a wheel event is from mouse wheel or touchpad on Windows?
onWheel: {
var horizontal = false;
var isTrackPad = wheel.pixelDelta !== Qt.point(0,0);
if (Math.abs(wheel.angleDelta.x) > Math.abs(wheel.angleDelta.y)) {
delta = wheel.angleDelta.x
horizontal = true
}
else {
delta = wheel.angleDelta.y
}
if ((isTrackPad && horizontal) || (!isTrackPad && wheel.modifiers === xxx.ScrollModifiersH)) {
...
}
}
You could try WheelHandler instead like the following. I can't tell if it will work on Windows as I'm using Linux and there the Mouse is the same as the Touchpad.
acceptedDevices
Note: Some non-mouse hardware (such as a touch-sensitive Wacom tablet,
or a Linux laptop touchpad) generates real wheel events from gestures.
WheelHandler will respond to those events as wheel events even if
acceptedDevices remains set to its default value.
WheelHandler {
acceptedDevices: PointerDevice.Mouse
onWheel: console.log("WheelHandler", "Mouse")
}
WheelHandler {
acceptedDevices: PointerDevice.TouchPad
onWheel: console.log("WheelHandler", "TouchPad")
}
Or you can get the QInputDevice::DeviceType from the WheelEvent. But same story here, if your OS doesn't make a difference between mouse or touchpad it will always give you QInputDevice::DeviceType::Mouse. The matching enum in QML is PointerDevice.Mouse.
MouseArea {
anchors.fill: parent
onWheel: function(wheelEvent) {
console.log("device", wheelEvent.device.type)
}
}

Qt isfullscreen = no such value

i made a special videoplayer based of hikvision sdk with qtcreator in cpp
i have an void :
void QtVsPlayer::FullScr()
{
if (QtVsPlayer::isFullScreen()) {
QtVsPlayer::showNormal();
this->ui->menubar->setVisible(true);
if (!Zoomed)
this->ui->statusbar->setVisible(true);
} else {
QtVsPlayer::showFullScreen();
this->ui->menubar->setVisible(false);
this->ui->statusbar->setVisible(false);
}
return;
}
this void work, i have fullscreen video.
now in mousemove event i have
if (!this->ui->actionMasquer_les_controles->isChecked() and
WVideoCtrls->isHidden() and
this->ui->actionAuto_hide_controls->isChecked()) {
if(!Zoomed and QtVsPlayer::isFullScreen() == false)
ui->statusbar->setVisible(true);
WVideoCtrls->show();
WVideoCtrls->activateWindow();
WVideoCtrls->raise();
this->centralWidget()->lower();
this->centralWidget()->stackUnder(WVideoCtrls);
}
if (QtVsPlayer::cursor() == Qt::BlankCursor) {
QtVsPlayer::unsetCursor();
}
return;
the goal is to display videocontrols, like play, pause and so on, but not the status bar in full screen, but it is shown, zoomed is false but isfullscreen is no such value
i tried ui->centralwidget, this->isfullscreen, is->fulsreen, & , &&, and, but statusbar is displayed in fullscreen when mouse move and hide after my timer hider

ChangeEvent blocks QMDISubWIndow

n my App I use a QMDIArea. In this I open now a subclassed MDIChild that has a master class. Inside the master class I set the virtual changeEvent of the subwindow. But if I use this event I cannot move the window in the QMDIArea anymore and the sub window is not create in maximized.
If I remove the Event from the class it works again well. Do I use the Event the wrong way?
MdiChildBase.h
private:
virtual void changeEvent(QEvent * e);
MdiChildBase.cpp
void MdiChildBase::changeEvent(QEvent * e) {
if(e->type() == QEvent::WindowStateChange && this->isActiveWindow()) {
// .. this is now the active window
qDebug("Iam active now");
}
QWidget::changeEvent(e);
}
Ok after reading the docs and try something around the solution for this question is:
void MdiChildBase::changeEvent(QEvent * e) {
QMdiSubWindow::changeEvent(e);
if(e->type() == QEvent::WindowStateChange && this->isActiveWindow()) {
// .. this is now the active window
qDebug("Iam active now");
}
}

How to detect if a window has been activated?

Focus events don't work because they're not sent if you activate your window by clicking on its non-client frame. Also, if you click the internal components of the window THEY will get the focus event, not your window, but the window will still be activated, even if it wasn't active or focused before.
The event you want is QEvent::WindowActivate. Override event() to process it:
bool YourWidget::event(QEvent *e)
{
if (e->type() == QEvent::WindowActivate) {
// window was activated
}
return QWidget::event(e);
}
Qt provides several virtual event handling functions you can use. Since the activation of a window changes its state, you want to handle some change events:
void MyWidget::changeEvent(QEvent * e) {
if(e->type() == QEvent::ActivationChange && this->isActiveWindow()) {
// .. this is now the active window
}
}
References
changeEvent
isActiveWindow

In a QWizard, the next button cannot accept key press event, but accepts mouse press event?

I have a class inherits QWizard, and add 2 independent QWizardPage(s). Before go to the next page, I want to do some job (i.e. check internet connection) on the first page. User may click 'next' button by mouse, or directly press enter/return by keyboard since the 'next' button is focused by default. So I install a eventfilter for the button:
button(QWizard::NextButton)->installEventFilter(this);
Then in the wizard class implement the event handling code:
bool MyWizard::eventFilter(QObject *watched, QEvent *event)
{
if (watched == button(QWizard::NextButton))
{
if (currentId() == startPageId)
{
if (event->type() == QEvent::KeyPress)
{
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
if (keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Enter)
{
// Do something. Cannot be reached.
}
}
else if (event->type() == QEvent::MouseButtonPress)
{
// Do something. Can be reached.
}
}
}
return QWizard::eventFilter(watched, event);
}
As I tried many times, clicking mouse can always make my event processing code run, but pressing key makes nothing to do. Another curious thing is, press mouse on button without releasing, then move away and release, the wizard stays on first page, now I can press key and all that is OK.
Could any one help to find the reason, is that a Qt bug? how can I make the key event work properly?
Try another simple solution without installing event filter.Use QkeyPressEvent in your main App.
void YourAppClass::keyPressEvent(QKeyEvent *e)
{
if(Nextbutton->hasFocus() && e->key()== Qt::Key_Return || e->key() == Qt::Key_Enter)
{
Do your job//I guarantee this will be reached upon pressing return with button focus
}
}
You can add mouse-click functionality in nextbutton's clickevent().

Resources