How to set cursor when it is in some area? - qt

I have some rectangle link area on my widget. What is the best way to make cursor Qt::PointingHandCursor when it is in this area?

The QWidget class has a cursor property that you can set with the cursor you wish displayed when the mouse is above it.
EDIT:
Without more detail on what you are trying to achieve, I can only assume you're making your life much more difficult than it needs to be. You can create a QLabel widget to handle the link and then place the label on the menubar automatically.
QLabel *link = new QLabel("<a href='http://doc.qt.io'>Qt Documentation</a>");
menuBar()->setCornerWidget(link);
All the text formatting, cursor display and user interactions are handled by existing code in the Qt classes. The only thing you need to do yourself is to handle what happens when the user clicks on the link, that you can do by connecting a slot to the QLabel::linkActivated(const QString &) signal.

Related

Buttons in vertical layout in QDialog with return value

I want to create a QDialog with Qt that looks somewhat like this:
The desired properties here are:
I can add a text to the dialog explaining the question behind it
I can add several buttons that are in a vertical layout
I can retrieve the value of the clicked button, i.e. I know if the user cancelled or clicked 1, 2 or 3 - ideally I can emit a signal with the corresponding value as parameter.
The dialog has a certain minimum height and width.
I have used a QMessageBox before for this purpose, but I can't get it to use a vertical layout. I have experimented with a QDialogButtonBox and a QDialog, but I can't really figure out how to get my desired return value easily.
A piece of code creating this dialog with code how to retrieve the clicked value would be great!
Did you try a QDialog widget? you can add QDialog without buttons to your project. In UI designer, add Vertical layout, label, and buttons.
In your class define your signals and emit it when the user clicked on buttons.

QCompleter popup position

I'm having trouble trying to move the QCompleter popup view position.
I tried the QCompeter:complete and it's pops the completer view in the position as I wanted.
But if I start typing it close it, and open the completer in the 'default' position.
I also tried the QCompleter:setPopup() function.
I create a QListView and I tried to moved to different position.
And still the QCompleter popup view remains in the same position.
In my project I'm using a QFrame that wrap QLineEdit.
And I want that the completer view will get the QFrame position.
I succeed to set the completer view width via setFixedWidth() function.
but not to move the position.
Any suggestions ?
Thanks.
I suggest setting the CompletionMode to InlineCompletion, so there will be no popup. Then make your QListView indepedant of the QLineEdit; just react to signals that indicate when a view types some text, leaves the QLineEdit, etc (hint: subclass QListView) and sets the text in QLineEdit when a user selects a value from the list.
I think it will be difficult to override the placement since QCompleter takes ownership of your QListView. (Personally I think it does not make much sense to place the completion list somewhere else than next to the input field, but alas...)

How to detect a mouse click inside a tooltip in Qt?

I have a Qt application in which certain QLabel's display a tooltip if a certain internal condition occurs.
Since the tooltip has a timeout and is hidden by Qt automatically, the tooltip is kept alive by the application by showing the tooltip every 3 seconds (I did not find any mechanism to tell Qt to show a tooltip indefinitely).
The tooltip is displayed until the user clicks on the QLabel itself: the tooltip is not refreshed any more and disappears.
I now have a new requirement that the tooltip should also disappear if the user clicks on the tooltip itself. Is there a signal that is sent when the user clicks on a visible tooltip? Or is it necessary to use some more sophisticated technique?
EDIT
I have checked my code again, here is some extra information.
Qt does detect a mouse click on a tooltip and hides it, but the application immediately shows the tooltip again.
What I would like to do is that Qt informs my code of the mouse-clicked event, so that it stops showing the tooltip again and again. I have two possible solutions in mind, but I do not know if either of them is technically feasible:
Remove tooltip timeout: when a tooltip is shown, it remains visible as long as the user does not click on it. How can I display a tooltip without a timeout in Qt?
Keep the tooltip visible by repeatedly showing it; detect a mouse clicked on the tooltip in order to stop the keep-alive loop. How do I receive a signal when the user clicks on a tooltip?
Under the hood, the actual class that implements the tooltip is a private QLabel-derived class called QTipLabel:
http://qt.gitorious.org/qt/qt/blobs/4.7/src/gui/kernel/qtooltip.cpp#line119
There's nothing published in the interface to get at an instance of that class from QToolTip, so intercepting clicks would only be done with some sort of ill-advised hack.
That said: among the events that should "hideTipImmediately" is QEvent::mouseButtonPress...in fact, there's an event filter installed so that any click in the app will hide it:
http://qt.gitorious.org/qt/qt/blobs/4.7/src/gui/kernel/qtooltip.cpp#line325
So if you're not seeing the tooltip disappear when it's being clicked on, there's a bug. (Clicking on tooltips hides them for me in Qt-based apps under Kubuntu.)
Note the definition of QToolTip::showText:
void QToolTip::showText ( const QPoint & pos, const QString & text,
QWidget * w, const QRect & rect ) [static] Shows text as a tool tip,
with the global position pos as the point of interest. The tool tip
will be shown with a platform specific offset from this point of
interest.
If you specify a non-empty rect the tip will be hidden as soon as you
move your cursor out of this area.
The rect is in the coordinates of the widget you specify with w. If
the rect is not empty you must specify a widget. Otherwise this
argument can be 0 but it is used to determine the appropriate screen
on multi-head systems.
If text is empty the tool tip is hidden. If the text is the same as
the currently shown tooltip, the tip will not move. You can force
moving by first hiding the tip with an empty text, and then showing
the new tip at the new position.
Thus, you can supply the rectangle in which the QToolTip is to be presented. Then, if what you want to do is close the QToolTip only when the user clicks on it, you can capture mouseButtonPress events as #HostileFork pointed out and then close the tooltip only when the coordinates of the event fall within it.

Qt4: QLabel -> QPixmap -> click to open URL

I have a QLabel without any text but with a QPixmap image. I can not figure out a way to open a url when the user clicks the image. I can not use text in QLabel here.
You don't need to put text in, but you do need to switch to either a subclassed label or to use a QPushButton instead. If you use a QPushButton (which is the easiest) then you can change the relief layout so it looks flat again (since the default button doesn't).
You could install an event filter on the label and filter for mouse press events. For an example, see my answer to a similar question.

How to remove focus from a QLineEdit when anyplace else on the window is clicked

I'm working on a custom Qt button that allows you to edit the text on the button if you double click it. When the button is double clicked, a QLineEdit appears where the text on the button is allowing the user to edit the text on the button. My requirement is that if the user clicks anywhere in the application window, the QLineEdit should disappear and cancel the edit operation. This works in some cases. Specifically, it works if I click on anything that is capable of text entry. Other portions of the window don't work as expected. I'll click on a blank portion of the application window, and the QLineEdit retains its focus. How can I remove its focus in these cases?
I've found a solution that seems to work, though I'm still open to other options if there are any. I'm using PyQt4, so my example is in python:
Create a subclass of QLineEdit just so I have a new type. I don't want or need this behavior on all QLineEdit instances; just these specific ones.
class MyLineEdit(QtGui.QLineEdit):
pass
Now, in my QMainWindow subclass, I override the mousePressEvent() implementation. It gets the currently focused widget. If that widget is of type MyLineEdit, clear the focus.
class MyMainWindow(QtGui.QMainWindow):
def ...
def mousePressEvent(self, event):
focused_widget = QtGui.QApplication.focusWidget()
if isinstance(focused_widget, MyLineEdit):
focused_widget.clearFocus()
QtGui.QMainWindow.mousePressEvent(self, event)
def ...
This gets me the behavior I'm looking for so that if the user clicks anywhere on the application's window, the focus is cleared.
Edit: I did find one caveat to this. I have a QTreeView in the main window. If the user clicks on the tree view, focus is not removed from the text edit field.
Catch the clicked() signal of your parent widget and call yourLabel->clearFocus() (that unfortunatelly happens to not be a slot, making things more complicated) there.
I followed Grant Limberg instruction here but figured out that, in my case, a simple:
QApplication.focusWidget().clearFocus()
would fix the problem.
I'm not sure if this also works in Qt4 (I'm using PyQt5) but you can change the FocusPolicy of the QMainWindow or parent widget to clear the focus in the QLineEdit. As per https://doc.qt.io/qt-5/qwidget.html#focusPolicy-prop
I've changed the policy of my QMainWindow to Qt.StrongFocus and it worked like the functionality described in the question.
If done in C++ I would do something along the lines of:
connect(myWidgets->MyLineEdit, SIGNAL(returnPressed()), this, SLOT(onLineEditDone());
void onLineEditDone()
{
myWidgets->MyLineEdit->clearFocus();
}
For this particular case I would use editingFinished() instead of returnPressed(), probably, but I would NOT use textChanged(QString).

Resources