This question already has an answer here:
Passing extra arguments through connect
(1 answer)
Closed 2 years ago.
so I'm currently working on a PyQt5 GUI, and as always need to connect some signals to method calls.
Naturally I've looked up a standard syntax to do so and used it throughout my entire project (it's been working so far with more then 20 different signals)
That syntax is: self.widget.signal.connect(lambda x: whatever)
So I recently got to the point of connecting the QPlainTextEdit signal "textChanged()" to one of my methods and it just didn't work. I've tried replacing my method with a simple print(text) but that didn't help. My next step was testing wether another signal of the same widget worked and it did!
So now I have the following code:
self.plainTextEdit.textChanged.connect(lambda x: print("testTextChanged"))
self.plainTextEdit.blockCountChanged.connect(lambda x: print("blockCountChanged"))
and the upper signal doesn't trigger, but the lower one does.
I've already read the documentation of QPlainTextEdit, textChanged() should be a valid signal of this class. I've also used the same signal on several QLineEdits within my project.
Does anyone have any suspicion as to why this behaviour is occuring? Maybe I did make an error that I just can't recognize. (I'm trying to trigger the signal by simply typing into the textBox on the GUI, whereas blockCountChanged get's triggered whenever I'm pressing enter while editing it)
So, the comment of musicamente (comment on the question) did answer it. The reason it did not work is, because the textChanged signal of QPlainTextEdit does not have any parameters (QLineEdit textChanged does f.e.). That's why the lambda should not have and parameters -> the correct code should be:
self.plainTextEdit.textChanged.connect(lambda: print("testTextChanged"))
PS: just answering this if someone searches for the same stuff.
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I am using TreeView with a MyTreeModel (which inherits from QAbstractItemModel). This model is fed by a tree structure with nodes as it appears in the documentation.
https://doc.qt.io/qt-5/qtwidgets-itemviews-simpletreemodel-example.html
https://doc.qt.io/qt-5/qtwidgets-itemviews-editabletreemodel-example.html
https://doc.qt.io/qt-5/model-view-programming.html#using-drag-and-drop-with-item-views
I have the whole subject of drag and drop between elements of the tree perfectly implemented. As the doc says well, I have reimplemented mimeData, mimeTypes and dropMimeData for it.
Video of it:
https://mega.nz/#!bkoTDQSI!YgVn6jIAPJ86fhexzsGySbhrPwQAK5IwlTTeb5L-sQ4
The problem is that I want to do actions programmatically right after the drop in relation to the item that was dropped.
I want to expand the item after the drop and I want to select it. The view on the right depends on the currentIndex.
I have tried everything. Make the selection after:
rowsInserted
dataChanged
currentChanged
changeEvent
dropEvent
eventFilter
Nothing works because if I try to change the selection after those methods, I break Qt inside causing the not terminated drops not to work well. I need to wait for all the signals derived from the drop to finish to execute the select and expand command.
I am desperate, I have watched how TreeWidget behaves and has the same problem as me: when the drop is made the row selected is wrong and the node collapsed.
They have solved it for me in the Qt forums.
I have connected custom signals by adding the parameter QtCore.Qt.QueuedConnection in connect.
Here the solution:
https://forum.qt.io/topic/114716/treeview-wait-until-the-drop-is-complete-to-perform-another-action/3
I'm not sure why anything should break. Run your model throught the model test to make sure it's implemented 100% according to Qt's
expectation
adding Qt::QueuedConnection as the 5th argument of your connect ststement should ensure your code gets executed after the move is
completed and control is given back to Qt's event loop
This question already has answers here:
PyQt - how to detect and close UI if it's already running?
(3 answers)
Closed 7 years ago.
I have created a pyqt4 app and I want to make it so only one instance (of QApplication) is allowed to run.
The program reads and writes audio files, and if more than 1 instance is running, Windows (linux is fine) throws errors that 2 programs are trying to access the same files. I see a lot of java and C apps that will display a simple dialog if the program is already running, I just want to know how to do this in pyqt4.
A little help?
This kind of programming pattern is called a "singleton" instance or a "singleton application".
Usually it is done with a global mutex or by locking a file early in the life of the program.
And when you program launches, if the file handle is already locked, then you exit.
Qt Solutions has it here: http://doc.qt.digia.com/solutions/4/qtsingleapplication/qtsingleapplication.html
https://qt.gitorious.org/qt-solutions/qt-solutions/source/841982ceec9d30a7ab7324979a0fd5c9c36fd121:qtsingleapplication
It would probably take a bit of work to get those global mutexes/locks to work in pyqt, since pyqt doesn't have the qt-solutions part in it yet as far as I could tell.
Here is an alternative that uses a cross platform python script:
Python: single instance of program
Hope that helps.
Thanks. I Used https://gitorious.org/qsingleapplication/qsingleapplication/source/ca13324b0f5bdfcaf4e379a78108f0bd85fed98a:qSingleApplication.py#L66 And Called QSingleApplication On My MainWindow And Works Fine
I use Python in combination with the gtk3 and the GTKGLExt fork from https://github.com/tdz/gtkglext so I can use the gobject introspection feature to use Gtk3 from python.
I created a Gtk.DrawingArea to draw my OpenGL stuff. Everything works fine as long as I have just one instance of this widget.
However, I use a Gtk Notebook to have multiple instances of this widget present in different pages of the notebook (one widget per page).
Sometimes (meaning in a non deterministic way) the program crashes with a segmentation fault. I ran a stacktrace using gdb and located the problem to be the call to "gtk_widget_end_gl" which is placed at the end of my drawing, realize and configure handler methods (of course there is a gtk_widget_begin_gl at the beginning of each of those as well).
Here is the relevant excerpt from the stacktrace:
0 0xb1170b58 in _gdk_x11_gl_context_impl_get_current () at gdkglcontext-x11.c:514
1 0xb116c094 in gdk_gl_context_get_current () at gdkglcontext.c:244
2 0xb116c0b4 in gdk_gl_context_release_current () at gdkglcontext.c:215
3 0xb4d04592 in gtk_widget_end_gl (widget=0xa175608, do_swap=0) at gtkglwidget.c:549
and below is a minimal example of my realize method where the problem occurs where "widget" is an instance of Gtk.DrawingArea:
def on_realize(self, widget, *user_data):
if not GtkGLExt.widget_begin_gl(widget):
return False
gl.glClearColor(BACKGROUND_COLOR[0],
BACKGROUND_COLOR[1],
BACKGROUND_COLOR[2],
BACKGROUND_COLOR[3])
GtkGLExt.widget_end_gl(widget, False)
Since I am pretty much clueless why this problem occurs sometimes (around every 5th time a new widget is created) I wonder if anyone ever has experienced the same or can reproduce the problem or help me to find a solution.
I need to say that I don't manually create an OpenGL context here since in the provided examples this never seemed necessary and I figured the widget would do this on it's own. The stacktrace implies that there seems to be a problem getting the context. Whats startles me is the fact that this only happens sometimes. So if someone could even hint me how to tackle this problem I would be very glad as I am not an experienced C programmer.
I need some advise about how to read PyQt's documentation. Because on my own I can hardly figure anything out. I'm a programming newbie so sorry if my question is confusing. I'll try to explain the best I can :)
This is an example of where I got stuck. I was experimenting around with QListView. Basically just trying to print out data of what I have selected in the view. I got stuck until Justin, a very patient Python tutor, showed me this bit of code.
listView.clicked.connect(B)
def B(index):
record = sqlmodel.record(index.row())
It connects a clicked signal from QListView to function B. I was very surprised that right away the clicked event sends index to B by itself. I tried to look through QListView's documentation but can't find anything that explains this.
http://www.riverbankcomputing.co.uk/static/Docs/PyQt4/html/qlistview.html
In this case, where in the docs should I look at to learn about this clicked event, and the index it sends out?
Would really appreciate any advise. :)
Unfortunately PyQt documentation is not full. Better source for knowledge is Qt documentation.
In your case QTableView inherits QAbstractItemView, and there is no clicked signal in QTableView docs, you can find it in List of all members, including inherited members page. And you can see, that this signal comes from QAbstractItemView and it's defined as:
void QAbstractItemView::clicked ( const QModelIndex & index )
Here you can see type of function arguments (clickable).
So, index passed to you function will be instance of QModelIndex and it has row method.
If you are confused with C++ syntax, another option is to use PySide documentation, which is more Python friendly.
QAbstractItemView.clicked in PySide docs
The following code connects QTableView's clicked signal to your function. QTableView emits clicked whenever someone clicks an item, which means that your function will be called automatically, since it's connected to that signal.
listView.clicked.connect(viewItemClicked)
Or am I missing something in your question? Read up on signal-slots in Qt if the above is unclear. (PyQt allows any function (i.e. python callable) to be connected to a signal, not just a slot (as it is in C++).
I have an application in which I would like to connect whatever signal is emitted when a pyqt4 dialog is displayed in order to do execute an initial method. I don't want the method to be called in the __init__ method for a number of reasons. I've spent quite some time searching but I have yet to find an answer. I'm sure there is a simple solution that because of my inexperience I am overlooking as I can do this in wxPython. Suggestions?
There is no signal emitted on first display, instead, you will have to intercept the first resizeEvent or paintEvent by overloading these methods (as you don't want to initialize from the __init__ method).
Another option would be to add your own showAndInit method, that initializes and then calls show.