PDA

View Full Version : Get the Window Visible State when it is partially visible



sraju
14th October 2013, 17:25
Dear All,

I am working on an application where in which I need to determine the state of the window based on the visibility state.
I have an enum declared as follows:
enum APP_WIN_STATE
{
APP_WIN_INACTIVE, // Window in not associated with a display
APP_WIN_OBSCURED, // Window is completed obscured on a display
APP_WIN_PARTIAL, // Window is partially obscured on a display
APP_WIN_VISIBLE, // Window is completely visible on a display
};

I need to set the window state based on their visibility states.



#include <QApplication>
#include <QPalette>
#include <QWidget>
#include <QDebug>
#include <QString>

void printWidgetProperties(QWidget *pWidget, QString message)
{
qDebug() << message;

QRegion visRegn = pWidget->visibleRegion();
if (visRegn.isEmpty())
{
qDebug() << "is *not* visible";
}
else
{
if(visRegn.boundingRect() == pWidget->rect()) {
qDebug() << "is fully visible";
} else {
qDebug() << "is partially visible";
}
}
}

QWidget* createWidget(int top, int left, int width, int height, QColor color, QWidget *pParent = NULL)
{
QWidget *pWidget = new QWidget(pParent);
pWidget->setFixedSize(width, height);
pWidget->setGeometry(top, left, width, height);

QPalette pal;
pal.setColor(QPalette::Background, color);
pWidget->setAutoFillBackground(true);
pWidget->setPalette(pal);

return pWidget;
}

int main(int argc, char *argv[ ])
{
QApplication app(argc, argv);

QPalette pal;
QWidget *pMainWin = createWidget(0, 0, 480, 272, Qt::white);

// QWidget * pWinG = createWidget(10, 10, 420, 260, Qt::green, pMainWin);
QWidget * pWinG = createWidget(0, 0, 480, 272, Qt::green, pMainWin);

// QWidget * pWinB = createWidget(190, 86, 100, 100, Qt::blue, pMainWin);
QWidget * pWinB = createWidget(0, 0, 480, 20, Qt::blue, pMainWin);

// QWidget * pWinR = createWidget(380, 86, 70, 50, Qt::red, pMainWin);
QWidget * pWinR = createWidget(0, 20, 480, 252, Qt::red, pMainWin);

QWidget * pWinY = createWidget(380, 86, 70, 50, Qt::yellow, pMainWin);

pMainWin->show();

printWidgetProperties(pWinG, "Widget Green");
printWidgetProperties(pWinR, "Widget Red");
printWidgetProperties(pWinB, "Widget Blue");
printWidgetProperties(pWinY, "Widget Yellow");

return app.exec();
}

In the above code I am trying to determine each widget state based on the visibility region. My expectations are as follows from the code:
a. Widget Green - Completely Obscured
b. Widget Blue - Cimpletely Visible
c. Widget Red - Partially Visiblle
d. Widget Yellow - Completely Visible

But the above code gives me an output that
"Widget Green"
is *not* visible
"Widget Red"
is fully visible
"Widget Blue"
is fully visible
"Widget Yellow"
is fully visible

Query: How do we determine that widget is partially visible (in my case yellow widget is enclosing some part of the Red Widget and hence Red Widget is partially visible)?
Is there a way to say that a Widget (Red Widget in my example) is partially Visible in Qt?
Kindly do the needful

Regards
SRaju

stampede
14th October 2013, 18:48
Try this:


if(visRegn.boundingRect() == pWidget->rect() && visRegn.rects().count() == 1) {
qDebug() << "is fully visible";
}

It assumes that if visible region is just one single rect equal to whole bounding rect, then widget is fully visible.

sraju
14th October 2013, 19:02
Thank you very much , it worked well. If there are any overlapping rectangles then it is partially Visible otherwise it is completely visible.

Regards
SRaju

rion
2nd January 2018, 13:04
Doesn't work for me. visRegn.boundingRect() and pWidget->rect() are always equal and visRegn.rects().count() always return 4 when the window is visible (setVisible(true))
I tried to implement next..

I have a window and a tray icon. There are 3 possible actions on click on the tray.
1) raise the window to front if it's behind of some others windows
2) show and raise it if it's currently in the hidden state.
3) hide it if it's currently fully visible.

I guess there is no other Qt way to do this. So may be it's better to implement DE specific tray plugins for my application. For example KDE has a concept of "associated widget" in their KStatusNotifierItem. According to comments in the code it seems it does exactly what I want.