I've to deal with a scientific application and thus have to use RTF at many place (think about displaying units with exponents mainly).
I've implemented a delegate to deal with tables and drop box and it works mostly fine. (implementation : http://pastebin.com/FuCbGqkY , header : http://pastebin.com/D6hxeWdF ).
However, I've been into a major issue : it looks like the "button" part of the QComboBox is not rendered with the delegate (it only applies to the drop down box). Is there any way to have the text in the combobox when it's not dropped displayed correctly ? If not, what do I have to do ? Subclass and overwrite paint method ? Looks like a lot of pain and basically it makes the delegate useless.
Any clue ?
Consider QComboBox::lineEdit() method. You can try to apply your changes to the QLineEdit directly if it's possible. Otherwise you can subclass QLineEdit and change its behaviour to what you want, and then insert it using QComboBox::setLineEdit. Maybe you will need to make the combo box editable in order to use this.
Related
I'm migrating a cell-based NSTableView to be view-based. With NSCell, to determine if a cell was highlighted (e.g., to draw the text in white instead of black), I looked at the NSCell highlighted property.
What's the NSView version of this? I can't find anything like this in the docs.
The easiest way to do this is to simply subclass NSTableCellView. All the documentation says that you can subclass either NSTableCellView or NSView, e.g., Table View Programming Guide for Mac:
Drag an NSTableCellView object (or a custom view) from the object library to the appropriate column in the table view. ... Typically, the view class is a subclass of NSTableCellView.
It doesn't say what this is, or why you'd want to use it. It looks like an NSView which has an NSTextField and an NSImageView, and that's it -- so if you're not making a view that has these, it's tempting to ignore this class and just subclass NSView.
Interestingly, though, if you have any NSTextFields in an NSTableCellView (even if you don't use the textField property for this!), they automatically use the correct light/dark coloring.
In particular, it seems that the backgroundStyle property of NSTableCellView is what causes the text value to actually change. The documentation says:
The default implementation automatically forwards calls to all subviews that implement setBackgroundStyle: or are an NSControl, which have NSCell classes that respond to setBackgroundStyle:.
NSTextField is an NSControl with an NSCell, of course, so it gets this called on it.
While it's not exactly clear in Apple's documentation (what does "this" refer to?), it seems that NSTableView calls -setBackgroundStyle: on any view that defines it. So if you don't want to subclass NSTableCellView, you can alternatively just add a property to your own NSView:
var backgroundStyle: NSBackgroundStyle
and have your drawing code use that.
I need to make a QLineEdit with non-editable word blocks.
For instance, imagine I drop a word (that actually represents a value) in a QLineEdit.
I would like to write normally on the QLineEdit, BUT if I try to move the cursor inside a word it would move over it, ie, place the cursor at the end/begining of the word.
Also, I would like the word to always show a certain highlight over it, with different colors (to emulate a box that would wrap it).
Any ideas on how to do this? Would a QTextArea be better for this? I was thinking of a QLineEdit because it would actually be inside a QTableWidget cell, so I think it may have more or less the same capabilities, am I wrong?
UPDATE I found these two functions that actually might be helpful for QLineEdit: cursorWordBackward() and cursorWordForward(), so this might help move over the words. Anyone has examples of this?
UPDATE 2 As QLineEdit does not support rich-text, the "highlight" feature I required can only be achieved with a QTextEdit. This has other issues: QTextEdit does not have the functions I mentioned in the first update above, and I don't know if it is possible to put a QTextEdit inside a QTableWidget cell.
QLineEdit can contain only plain text and certainly can't do this. I was thinking about QTextEdit, it can display HTML. But looking at the documentation, I realized that there is no way to insert non-editable block in QTextDocument (which is used by QTextEdit). I think there is no simple solution.
You can try to implement it manually. Catch textChanged() and cursorPositionChanged() signals of QTextEdit, analyze its content and cursor position and modify them if user moved the cursor into non-editable block or changed its content.
Maybe you could achieve this by using an inputMask...
I'm developing simple HTML editor and I like to be able to drag and drop from a button that for example represent HTML text line and in the Qwebkit the HTML text line will be created does Qt support such action?
How should I approach such thing?
I believe it does, yes.
What you need to do is set the mime type of your drag event. See here for details. Then on the webkit side, you can read the drops mime type to see what it was.
You can then try one of the following approaches:
Subclassing QWebView to implement dragEnterEvent and dropEvent. You can use event->pos() in the dropEvent to get the position where the drop occured.
Implementing the drop in javascript within your page, eg setting up an event listener for drops or however its done (I've never tried this).
I'm showing a popup menu to select some values in a QTableWidget. The lowest item is a "Modify list" entry, when I select it a new window should automatically appear and the QComboBox should vanish and the cell return to a Qt::DisplayRole state.
Now Qt has all those nice API-calls like QTableWidget.edit() and QTableWidget.editItem(), what I'm really looking for is a QTableWidget.endEditing(), preferably without specifying the index of the cell, though I could get that using this call:
table.currentIndex()
… but I don't know if I can guarantee that the current cell is the cell being edited at all times.
Is there an API to close those kind of editors?
QTableWidget inherits 19 public slots from QWidget. One of those is setDisabled(), which should disable input events for that widget and all of its children.
I would try:
table.setDisabled( true );
table.setDisabled( false );
Although you said it does not work for you, there is an alternative method:
If you don't like that (the table loses focus, I believe), you can try using EditTriggers. For example:
table.setEditTriggers( QAbstractItemView::NoEditTriggers );
table.setCurrentItem(None) is what worked for me. (Don’t forget to block signals if you use some cellChanged/itemChanged slot function.)
This is with PyQt. For C++ I think replace None with NULL.
You may be able to use QTableWidget.closePersistentEditor() to close the editor. However, QAbstractItemView.closeEditor() may be closer to what you want, especially since you seem to be comfortable with the QModelIndex-based API and are already using a custom editor widget.
In my case, none of the options worked properly. So, I figured: I need to send the key press event to the line edit itself. The following works with QTreeView but probably does work with any other view or widget that opens a line edit to edit cells.
QWidget* editingWidget = treeView->findChild<QLineEdit*>();
if(editingWidget)
{
QKeyEvent keyPressEvent(QEvent::KeyPress, Qt::Key_Return, Qt::NoModifier);
QApplication::sendEvent(editingWidget, &keyPressEvent);
QApplication::processEvents(); // see note below
}
In my case, I wanted to start editing another field directly when having finished editing one item. That is why I put processEvents there, in most cases you can probably remove that line.
PS: yeah, it's C++, but should be easily adaptable to Python. I found this thread when I searched for the C++ solution, so maybe it helps anyone else, too.
I can't speak for list widgets. But, I got here trying to do something similar.
I was double-clicking a cell, and based on the column, bringing up a sub-form with a list, then when that was closed move to the next appropriate column based on the value selected.
My problem was I could get the value in the cell and "select" the next appropriate cell, but the original cell stayed selected in edit mode!
It finally dawned on me that my double-click was selecting the cell, ie. editing.
A single-click selects the cell but doesn't open an edit mode.
Side note: Never could get that sub-form to act truly modal, so I created a loop in the calling form: while the sub form was visible, with the only code being app.processEvents()
I've got a QTableView for which I want to display the last column always in edit mode. (It's a QComboBox where the user should be able to always change the value.)
I think I've seen the solution in the Qt documentation, but I can't find it anymore. Is there a simple way of doing it?
I think I could archive this effect by using openPersistentEditor() for every cell, but I'm looking for a better way. (Like specifying it only one time for the whole column.)
One way to get the automatic editing behaviour is to call the view's setEditTriggers() function with the QAbstractItemView::AllEditTriggers value.
To display the contents of a given column in a certain way, take a look at QAbstractItemView::setItemDelegateForColumn(). This will let you specify a custom delegate just for those items that need it. However, it won't automatically create an editor widget for each of them (there could in principle be thousands of them), but you could use the delegate to render each item in a way that makes it look like an editor widget.
There are two possibilities:
Using setIndexWidget, but Trolltech writes:
This function should only be used to
display static content within the
visible area corresponding to an item
of data. If you want to display custom
dynamic content or implement a custom
editor widget, subclass QItemDelegate
instead.
(And it breaks the Model/View pattern…)
Or using a delegate's paint method. But here you have to implement everything like enabled/disabled elements yourself.
The QAbstractItemModel::flags virtual function is called to test if an item is editable (see Qt::ItemIsEditable). Take a look at Making the Model Editable in the Model/View Programming documentation.
I can't see an easy way to do this, but you might be able to manage by using a delegate. I honestly don't know exactly how it would work, but you should be able to get something working if you try hard enough. If you get a proper delegate, you should be able to set it on a whole view, one cell of a view, or just a column or row.