I'm writing an app in Python with the PySide library. I have a QTableWidget that gets updated about every second. The thing is, I want to be able to change the data manually, and I thought that if I could find out whether or not the user is changing the data in the cell, then I could just prevent the program from updating this cell. Otherwise I get "kicked out" of the cell at each update.
Is this a good idea? Should I try something else and why?
How can I achieve my goal?
Many thanks
EDIT :
I know there exists an itemChanged signal, but what I'd really like to know is if there is a way to tell when the user is writing a new value in the cell, in order not to kick them out while editing.
In Qt Document:
void QTableWidget::itemChanged(QTableWidgetItem * item)
This signal is emitted whenever the data of item has changed.
Hope this will help you.
Edit:
QTableWidget uses a default itemdelegate(QItemDelegate instance) which has createEditor method and closeEditor signal.
You can reimplement createEditor which means edit starts, and connect the signal closeEditor which means the edit ends.
This may be the correct way.
Generally, you would handle this situation with the use of QItemDelegates, which allow you to control what cells are editable by the user, what types of controls they are given to edit the cells, and you can catch the data they input and validate or manipulate it before saving it to the model.
QItemDelegates only control edits being made using the view interface. If the table is being updated programmatically, the changes won't be sent to the QItemDelegate.
Here is an example of a QItemDelegate for a QTableWidget
Related
I have an app where this module is included. The module's job is to get and load RSS feed into the app, depending on the RSS feed provider that the user chose. The module does its job perfectly when I do not try to remove the entries from the previous query.
When I add .Clear() method to the sizer, containing all the programmatically added rows in the UI from a query, they are removed from memory but remain in the UI. I tried lots of different methods to make the UI update, but it doesn't. So now each set of new query rows gets painted over the old query rows.
Here's the gist to the module. You can directly run it:
https://gist.github.com/TiMladenov/64e55cafd4200373ba1f9ab82160cc00
Steps to reproduce:
1. Select the first or second dropdown option
2. Then select the third one
This way the problem will be more obvious.
I have tried calling .Layout(), .Update(), .Fit() to their respective objects that are making this module work, but none seem to do their job. Or I failed somewhere....
You were only missing one option for the Clear() method in the wx.BoxSizer class.
Change the line (87):
self.RssPanelList.Clear()
to:
self.RssPanelList.Clear(delete_windows=True)
The problem is that the method Clear() does not destroy the widgets by default. Therefore, you were emptying the sizer but the widgets remain and were painting on top of each other.
In the future it would be better if you post a MWE. Your chances of getting an answer will be a lot better with a MWE in the question.
I am making a GUI for a script in Python, using PySide Qt. I have a couple of checkboxes in the main window and I was wondering if it is possible to make them dependant to each other. What I mean is that, if I check one of them, all the others should become unchecked. So only one can be checked at a time.
Is there a comfortable way to do this? Otherwise I would just write a function to uncheck the others.
use QButtonGroup to make them as a group and you might want to derive a class from this and override the basic check/uncheck depending on how you want the checkboxes to behave
I finally managed to write a little app that reads from a sqlite database and show the results to a treeview. Another form (in another module) gives the ability to write new or update existing records. After writing to the database it closes the window
What I'm trying to do now is to update the "main" window (containing the treeview) to show the new dataset. I have managed so far to do this but a) the initial mainwindow stays there while a new instance of it opens on top of it showing the desired (new) dataset.
How would I make this work? Can someone give me suggestions/example?
Perhaps I need to say that the __init__ function of my mainwindow module does everything upon running: creates the gui, reads from the database and show all. I suspect that this may be the problem but having tryed almost any combination of breaking it into pieces (functions), I had no success
--EDIT--
OK I have many different functions __init__ now creates the main gui while others read the data from the DB and place it on a treeview.
I tried to use a timer but also this option doesn't seem to be apropriate as gtk.TreeView doesn't have such a method.
Finally I managed to figure this out, so I post this answer to my own question in case someone finds it helpful:
All I had to do was to .clear the list_store, rebuild it and use set_model to the TreeView.
The refresh function goes as below:
liststore.clear()
create_model_checks() # re-create liststore
treeView.set_model(liststore)
I'm using PyGObject but I think this is a question that could be adapted to all GTK, so if someone know how to do it using C or anything should work in python also.
I have two treeview, Active and Inactive, I load data from a Sqlite database and I can swap and drag & drop items from one to other.
This is just an aestetic thing, if I click on one item on one treeview I want that a previous selected item on the other be deselected.
It appears that nobody had to do something similar because I didn't found anything about it on the net.
At the risk of being too basic (perhaps I misunderstand the problem), to manipulate treeview selections, you use the GtkTreeSelection object returned from GtkTreeView.get_selection. You can attach to signals on this object, change the current selection,etc.
To turn off selection in the other view, you can get its selection mode property and set to GTK_SELECTION_NONE. To turn it back on upon clicking, my thought was that you could catch a grab-focus signal, set the selection mode to single in that view, and set the selection mode to none in the other view:
(connect view-1 'grab-focus
(lambda args
(set-mode (gtk-tree-view-get-selection view-1) "GTK_SELECTION_SINGLE")
(set-mode (gtk-tree-view-get-selection view-2) "GTK_SELECTION_NONE")))
(That code is using the guile-gnome wrapper but the concept should be the same in any language binding.) A problem with this approach is that now in order to make a selection you must click the tree view twice - once to grab the focus, and again to make the selection.
I'm still starting out with PyQt with QtDesigner using eric4 (and still studying python as a whole).
Anyway, as I've designed in a GUI using QtDesigner I've just made a Qlabel as a placeholder which is intended to update with the latest ID that has access to a SQLite database which I'm building. I want it to setlabel to change to the next slot available in ID primary key but I honestly don't know how.
I've tried to change the UI compiled form as I noticed that it is this line:
self.ID_Number.setText(QtGui.QApplication.translate("Dialog","IDLabel", None, QtGui.QApplication.UnicodeUTF8))
that sets the label of the supposed ID_Number which would communicate with the SQLite. But I always get a compiling error when I changed "IDLabel" to a variable. I've checked that it is supposed to be a constant but would it be possible that it can be a variable instead? Or am I doing wrong to use a QLabel in QtDesigner and I should use something else?
Any help in solving the wall I'm trying break is very much appreciated bows deeply
The translate function call is used for multi-language support. You can remove it in this case and simplify the code to the following.
self.ID_Number.setText(somePythonStringVariable)