How to start second QDialog window on side of MainWindow? - qt

I have a application in Qt, and a MainWindow. Now, I also added a helping QDialog which can be hooked up. This QDialog does not influence the programmflow, it just displays information.
But, it always starts on top of the MainWindow :/
SO I would like to start it on the side of the main window, so that it does not hinder the view to the main window?? How?

In my opinion , You should try this,
Use the overload of the QWidget::setParent() function to change the ownership of a QDialog widget, using set as NULL(but It will not share the parent's taskbar entry).
QDialog::show() returns control to the caller immediately, So it will not interfere in mainwindow flow.

Let's say, your application is in the full screen mode. Where then the QDialog should appear? It will be shown on the top and you won't be satisfied again.
If it doesn't influence the flow of the app then you are using it to communicate some sort of message. Can you use different ways? For instance, QStatusBar?
If not, why not to split the mainWindow with QSplitter or similar classes and provide an area where you can post all the info messages?

It sounds you want modaless dialog. In main window, use a slot to create the dialog.
void MainWindow::show_dialog()
{
if ( pDialog== NULL )
pDialog= new XYZ_Dialog(this);
QPoint p = pos();
QSize s = frameSize();
pDialog->setGeometry(p.x()+s.width(), p.y(), s.width()*1/2, s.height());
pDialog->show();
}
What I try to say is if the position of the new dialog bothers you, you set the position and size of it, before showing it.

Related

Docking with QWinWidget: Adding DockWidgetAreas to QWidgets

I have an application utilizing QWinWidget in a Win32 window. I'd like to add DockWidgets and the associated behaviour to it. There don't seem to be any exposed APIs for adding custom DockAreas, and the latest docs are sparse beyond adding DockWidgets to a QMainWindow. Older docs imply there once was a public QDockArea class.
So far, my best option appears to be adding a neutered QMainWindow (no top-level status, no frame, etc.) to the QWinWidget and going from there (second source).
I was hoping there was a way to add DockAreas to any container, but it doesn't appear that way. As a side note, QWinWidget is used to have window manager control with our custom frame requirement, but if there's a pure QMainWindow/QWidget way to have the same result (with Qt::FramelessWindowHint), I'd be happy to switch over.
As I said in the comments, I've added within my QWinWidget in my Win32 window a QMainWindow field. That is:
class QWinWidget : public QWidget
{
...
QMainWidget* mainWidget;
}
QWinWidget::QWinWidget()
{
mainWidget = new QMainWindow(this);
mainWidget->setWindowFlags(Qt::Widget); //1
}
Note that while the docs and some forum posts (from this post) indicate you need to set window flags explicitly due to the QMainWindow constructor setting Qt::Window, I tested it without the setWindowFlags() line (marked with //1 above) without noticing anything wrong.
So, this gives me the nice QWinWidget window I spent so much time making, inside a frameless Win32 window, with a QMainWindow child and all the features that brings along with it. Docking, menu bar, status bar, etc.

Qt Main window loosing focus and going to background unexpectedly

Going up the learning curve and everything has been making sense so far except for this one:
I have a main window from where I call one or more dialog like this:
d->setWindowFlags(Qt::CustomizeWindowHint | Qt::Window | Qt::FramelessWindowHint);
d->setGeometry(etc...
d->show();
The dialogs are not bound to the main window, and they are actually set to be displayed right beside the main window looking like an extension.
To close the dialogs I use a mouse 'enterEvent' on the mainwindow to send a close signal to the dialog(s) which will use hide().
void MainWidget::enterEvent(QEvent *event)
{
emit signal_related_close();
}
This works but randomly this causes a very annoying issue. When the signal is sent to close the dialogs, the main window would loose focus and go in the background (behind whatever application that is on the screen). Note that it does not minimize but only goes in the background and like I said it is random (about one out of 3 times I do it). I can't seem to get a pattern.
I initially thought the signal was messed up and instead used a dialog::leaveEvent() but that didn't help. I also tried using dialog::mouseMoveEvent and using that to hide the dialog but that would still randomly loose focus on the application.
The only method that doesn't loose focus is using a push button on each dialog that will initiate the same hide commands but that's not great for my UI. So it would seem that using the mouse enterEvent/leaveEvent,mouseMoveEvent will cause that random issue.
Anyone experienced this issue before? Any idea what could be wrong? Thx.
I can't explain why but this problem occurred when using QEvent or any mouse related event together with recursive children widgets. For example take this code in the parent widget constructor:
ChildWidget c1 = new ChildWidget (this);
ChildWidget c2 = new ChildWidget (c1);
Childwidget c3 = new ChildWidget (c2);
Using QEvent in the parent widget will randomly make the window go to the background and loose focus.
Setting all the ChildWidget to the same parent stopped the problem.

Detecting click outside QWidget

My application has non-rectangular popup widgets.
their class defines the following to achieve that transparency:
setAttribute(Qt::WA_NoSystemBackground, true);
setAttribute(Qt::WA_TranslucentBackground, true);
I also use:
this->setWindowFlags(Qt::Popup| Qt::FramelessWindowHint);
The problem is that on windows 7, an automatic "shadow" is being drawn on the bottom and right sides of my window. This is highly undesirable.
So, I tried using Qt::Tool instead of Qt::Popup
this->setWindowFlags(Qt::Tool | Qt::FramelessWindowHint);
This works visually. No shadow, but now a mouse click outside my widget window will not automatically close/hide it as it would have done with a Qt::Popup.
So, I need one of these two solutions:
A way to have Qt::Popup and get rid of that automatic windows shadow decoration
A way to let the Qt::Tool window a mouse click occurred outside of it.
One note: My application is built for Windows XP and up. I cannot use a Vista/Win7 only runtime DLLs, nor can i have a "Windows XP" and "Vista and up" separate builds.
Any advice will be welcome.
You could manually watch for when the focus changes from your Qt::Tool window. So basically you watch for when the focus goes onto another window of your process or when your application loses focus.
How to detect that my application lost focus in Qt?
Hope that helps.
Finally after realizing that no amount of "SetFocusPolicy" calls will allow me to receive those events for a Qt::Tool window, I've resorted to something else to fix my problem:
I kept the Qt:tool as Qt::Popup caused an undesired shadowing effect, tarnishing my owner draw frame. Removing this style cannot be done in Qt and I didn't want to mess with platform specific conditional code.
I installed an event filter with my Qt::tool window and I began receiving events that assisted me in understanding when other parts of my application were clicked, or if the application itself lost focus to another application. This was what I needed, functionality wise. I could also get an event when users click the non-client areas of the application's main window, such as the windows caption so that I can close it when dragging begins etc.
My solution for Windows 7:
QDialog *d = new QDialog;
d->setStyleSheet("background:transparent;");
d->setAttribute(Qt::WA_DeleteOnClose, true);
d->setAttribute(Qt::WA_TranslucentBackground, true);
#ifdef Q_OS_WIN
d->createWinId();
#endif
d->setWindowFlags(Qt::Popup | Qt::FramelessWindowHint);
d->show();
I set my QListView
d->setWindowFlags(Qt::Popup | Qt::FramelessWindowHint);
Install eventfilter and used MousePressEvent to hide qlistview widget.
MousePressEvent on list never comes to filter they produce other events which I didn't debug.
So if you want to design auto completer this will be perfect. Tested in Qt5.3.1.

QProgressDialog don't show up in the front

I have a QProgressDialog that needs to be popped up when application does the updates. It keeps hiding behind the windows.
dialog->setWindowTitle("Test");
QLabel * labl = new QLabel(this);
labl->setPixmap(QPixmap("icon.png"));
labl->setText("");
dialog->setLabel(labl);
dialog->setCancelButton(NULL);
dialog->show();
Am I doing something wrong here?
As a matter of fact you haven't provided enough information to solve the problem, my guess is you have forgotten to raise your dialog (because it was created and hidden earlier). So try to change the code to:
....
dialog->show();
dialog->raise();
dialog->activateWindow();
....
I had this same problem, when i had a modal QDialog and a QProgressDialog and the QDialog would always be on top despite the QProgressDialog coming from the QDialog itself. The issue was the lack of a parent assigned to QProgressDialog; just make sure that you assign the widget that spawns the QProgressDialog to be the parent.

How to show QGLWidget in full screen?

I have a QGLWidget as part of the UI of my application. It is NOT a central widget, there are a lot of others widgets around it. I want to show it full screen on user clicks the button. Similar functionality like on youtube video flash player.
I have tried to use showFullScreen with no effect.
I have read how-to-fullscreen-a-qglwidget and fullscreen-widget, but they suggest using showFullScreen.
Qt documentation states that for using showFullScreen widget must be an independent window. So I assume there should be some trick for this.
The solution I found:
void MyApp::on_fullscreen_button_clicked() {
QDialog *dlg = new QDialog(this);
QHBoxLayout *dlg_layout = new QHBoxLayout(dlg);
dlg_layout->setContentsMargins(0, 0, 0, 0);
dlg_layout->addWidget(glwidget_);
dlg->setLayout(dlg_layout);
dlg->showFullScreen();
bool r = connect(dlg, SIGNAL(rejected()), this, SLOT(showGlNormal()));
assert(r);
r = connect(dlg, SIGNAL(accepted()), this, SLOT(showGlNormal()));
assert(r);
}
void MyApp::showGlNormal() {
ui.glBox->layout()->addWidget(glwidget_);
}
The showFullScreen function works only on windows. From the Qt documentation:
A window is a widget that isn't visually the child of any other widget
and that usually has a frame and a window title.
A possible solution is the following:
When the user clicks the show full screen button
Create a new QGlWidget with no parent and set to it the contents of you QGlWidget
Use the showFullScreen function on it...
Maybe it is a better idea to subclass QGlWidget and pass in its constructor a pointer to another QGlWidget. The constructor should take the context of the provided widget and apply it to the new one.
On your subclass catch keyboard events. When the user press Esc emit a signal
In your base class catch this signal and connect it to a slot. In this slot hide the full screen QGlWidget and delete it.

Resources