How can I create a very dumb QWidget? - c++

I need a "dumb" QWidget which doesn't do anything, only provides a HWND and can be added as a child to other QWidgets. Specifically, it should not try to manage the mouse cursor (that is my problem with simply instantiating a QWidget). (motivation: I have an in-place activated ActiveX Control, which tries to change the mouse cursor sometimes, but the QWidget changes it back to the default, so it is flickering)

The code that does the cursor changing is not within QWidget, so no QWidget changes would fix the problem. It's QApplication that does it, from within the internal QApplication::dispatchEnterLeave(...). Eventually, it is qt_win_set_cursor that does the job.
I don't readily see how it'd be possible to change this behavior without changing Qt sources.
I would suggest reporting is as a Qt bug. Qt should be checking if the native cursor was changed upon leaving alien widgets, and if such, would need to preserve it. You'd have better chances of the bug getting fixed quickly if you'd provide a patch to actually fix the issue.
Workaround: To prevent flicker, set an application-wide cursor override using QApplication::setCursorOverride(). This fixes the flicker but won't fix the control being unable to change the cursor.

Related

How to Create Custom, Instant, Arrow-Shaped ToolTip with unique shape?

On many web-pages nowadays, you'll frequently see instant tooltips with an arrow that points to their target, similar to:
https://www.w3schools.com/css/tryit.asp?filename=trycss_tooltip_arrow_bottom
(More specifically, I'm looking for something like: https://www.youtube.com/watch?v=0Jedht9Arec)
How would you exactly replicate this in QT? I'm not necessarily looking for something super automated, just something that can be given a position to appear at, and a function call to remove it. Furthermore, if possible, it should have curved, anti-aliased corners.
I've tried using custom QToolTip, but it's behavior does not meet my standards. I've also tried a custom QDialog with a Popup flag, but it freezes the dialog it appears above.
Any recommendations on how to proceed?
As requested by two comments below, here is the code for the QDialog scenario previously referenced. Prepare yourself, it's a lot:
// Assuming "this" is the parent dialog
QDialog* popup = new QDialog(this, Qt::Popup);
popup->show();
This code blocks mouse hover events of the parent dialog (the "this" object), thus making it unsuitable as a tool-tip replacement.
You can use QWidget::setMask to specify custom shape of a widget. Additionally you'll have to set widget's window flags to include Qt::ToolTip.

How do I detect the change in text without changing the focus in QPlainTextEdit Class?

With this Qt construct,
http://doc.qt.io/qt-4.8/qplaintextedit.html
I have tabChangesFocus
but what if I want to detect a change on the input without having to tab to detect it? I want to change and then be able to hit save, no tabbing or focus changing necessary.
You can use the textChanged() signal to do this.
This is a piece of code you can slightly modify to fit the requirements.
connect(ui->textBox, SIGNAL(textChanged()), this, SLOT(DoSmth()));

How to avoid ugly overlap with too many dockwidgets in QMainWindow?

In our application, we have a variable number of dockwidgets because some of them are added by plugins that are loaded at runtime. Not all dockwidgets need to be visible at the same time necessarily. This depends strongly on what the user is working on and what plugins are active.
However, if too many dockwidgets are added programmatically with addDockWidget(...), they start to overlap each other (not in terms of tabs, but in terms of content of one being painted on the area of a different one, which obviously looks broken).
The user can move the dockwidgets to dockareas that still have space left, but the layout/main window successfully prevents (untabbed) re-addition to the "crowded" dockarea.
We do allow tabbed docks to allow the user to arrange the dockwidgets a required, but we don't want to enable QMainWindow::ForceTabbedDocks since this would constrain the number of simultaneously visible dockwidgets too much (one per dock area).
How can I prevent this or better control how dockwidgets are added?
Not answering your question directly but it might be worthwhile to actually forget about Qt and actually think of how the whole interaction should work. What are the user expectations? What should actually happen if 10 different plugins become active? Should they be docked or should they be floating or should they become pin-able docking windows with initial state as a small button on the MainWindow edges? I think once you do that ground work and come up with user interface mock-ups, you can then start looking at Qt and figure out if Qt provides a direct way to develop that interface and if not what additional components you will need to develop to get that interface working.
From my own experience, I had developed a similar interface long back but in MFC. The way we did it was that some of the docked windows were deemed to be must have and they would come up as docked. Then there were a set of windows that didnt need to be visible always but should be quickly available and their initial state was as hidden pin-able dock window which meant they came up as buttons on the MainWindow edge. Finally there was a third set that was not required by the user always and could be called in from File->View Menu. Once the user made it visible, the user typically would assign it to one of the first two groups or keep it afloat. This whole configuration was saved in a config file and from there onwards whenever the plugin was loaded/became active the last used state of the associated docking window was used. It though involved quite a bit of extra work but the end result was to the satisfaction of all users.
Have you tryed setDockOptions(QMainWindow::AllowNestedDocks)? I can't test it now but it may help.
By default, QMainWindow::dockOptions is set to AnimatedDocks | AllowTabbedDocks so you would want something like
setDockOptions(QMainWindow::AllowNestedDocks | QMainWindow::AnimatedDocks | QMainWindow::AllowTabbedDocks)
EDIT:
If you are having too many problems, you may be going about this the wrong way. Instead of using docks, you may want to try using QMdiArea with QMdiWindow. This may not work for your program, but its something to think about.
This is the solution I tried:
I created in QTCreator an empty project with a window, a minimalistic menu labelled "New Dock" and a DockWidget named dockWidget
This is the triggered() handler for my menu item:
void MainWindow::on_actionNew_Dock_triggered()
{
QDockWidget* w = new QDockWidget("Demo", ui->dockWidget);
this->addDockWidget(Qt::LeftDockWidgetArea,w);
this->tabifyDockWidget(ui->dockWidget,w);
}
tabifyDockWidget(QDockWidget* first, QDockWidget* second) is a QMainWindow method that stacks the second dockwidget upon the first one. Hope it helps...

What did QWidget* QApplication::mainWidget() become in Qt4?

I am porting an application from Qt3 to Qt4, and need a Qt4 replacement for QApplication::mainWidget() which used to return the top-level widget in Qt3. Does anyone know how to do this in Qt4?
Technically, any widget initialized with NULL is a top level widget so QApplication shouldn't assume that one of them is better than another.
The way I usually do it is to save a pointer to the "real" main widget somewhere, even a global variable or a singleton and reference it when needed.
I think topLevelWidgets() is as close at it can be.
Edit:
Yup. Qt4 added complexity (and power). There is no application wide MainWidget anymore. Many QMainWindows can be created and shown, and hidden, and shown again. This is a good thing, though :)
As shoosh noticed, QT3 behaviour can be easily simulated with global variable (yuck!) or QApplication subclass.
I think what you're looking for has been replaced by the QMainWindow class, which does allow you to set a set and get a central widget.

Show window in Qt without stealing focus

I'm using the Qt library to show a slideshow on the second monitor when the user isn't using the second monitor. An example is the user playing a game in the first monitor and showing the slideshow in the second monitor.
The problem is that when I open a new window in Qt, it automatically steals the focus from the previous application. Is there any way to prevent this from happening?
It took me a while to find it but I found it: setAttribute(Qt::WA_ShowWithoutActivating);
This forces the window not to activate. Even with the Qt::WindowStaysOnTopHint flag
If you want to make floating preview box/ any other widget just use below
thumbnail = new QLabel;
thumbnail->setAttribute(Qt::WA_ShowWithoutActivating);
thumbnail->setParent(0);
thumbnail->setWindowFlags(Qt::Tool | Qt::FramelessWindowHint|Qt::WindowStaysOnTopHint);
Qt::Tool is important flag to make it work. I mean not stealing focus.
Widgets don't accept focus by default but presumably you haven't created a plain widget? Which subclass was it? QMainWindow or something else?
It's possible the window subclasses default to accepting focus so try explicitly calling QWidget::setFocusPolicy with Qt::NoFocus before calling QWidget::show().
Also, make sure you're not calling QWidget::activateWindow() on the window or any of its widgets at any point.