Re: [PyQt] need help with sizing QStackedWidgets
Would appreciate some help here. I don't like how these stacked widgets take up all of this vertical space when the window is resized. I have tried setting a size policy to minimum on the stacked widgets but no luck. On Fri, Aug 23, 2013 at 4:02 PM, Eric Frederich eric.freder...@gmail.comwrote: Here is a small example. I tried putting a vertical spacer on the bottom yet these stacked widgets want to take up space when resized. #!/usr/bin/env python from PyQt4.QtCore import * from PyQt4.QtGui import * class TestWidget(QWidget): def __init__(self, labels, parent=None): super(TestWidget, self).__init__(parent) layout = QGridLayout() for i, output in enumerate(labels): layout.addWidget(QLabel(output), i, 0) combo = QComboBox() combo.addItems([ Slider, Spinner, ]) layout.addWidget(combo, i, 1) stack = QStackedWidget() horizontalSlider = QSlider() horizontalSlider.setOrientation(Qt.Horizontal) spinner = QSpinBox() spinner.valueChanged.connect(horizontalSlider.setValue) horizontalSlider.valueChanged.connect(spinner.setValue) stack.addWidget(horizontalSlider) stack.addWidget(spinner) combo.currentIndexChanged.connect(stack.setCurrentIndex) layout.addWidget(stack, i, 2) vertical_spacer = QSpacerItem(0, 0, QSizePolicy.Minimum, QSizePolicy.Expanding) layout.addItem(vertical_spacer, len(labels), 0, 1, 3) self.setLayout(layout) if __name__ == '__main__': import sys app = QApplication(sys.argv) ocw = TestWidget(['a', 'b', 'c', 'd', 'e']) ocw.show() sys.exit(app.exec_()) ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
Re: [PyQt] need help with sizing QStackedWidgets
Replying to self with a solution in case someone else comes across this problem. david_boddie on freenode's #pyqt channel helped me out. A solution was to call layout.setRowStretch(len(labels), 1) ... after adding the spacer. Another solution was to nest the grid layout into a BoxLayout and call addStretch. On Mon, Aug 26, 2013 at 9:36 AM, Eric Frederich eric.freder...@gmail.comwrote: Would appreciate some help here. I don't like how these stacked widgets take up all of this vertical space when the window is resized. I have tried setting a size policy to minimum on the stacked widgets but no luck. On Fri, Aug 23, 2013 at 4:02 PM, Eric Frederich eric.freder...@gmail.comwrote: Here is a small example. I tried putting a vertical spacer on the bottom yet these stacked widgets want to take up space when resized. #!/usr/bin/env python from PyQt4.QtCore import * from PyQt4.QtGui import * class TestWidget(QWidget): def __init__(self, labels, parent=None): super(TestWidget, self).__init__(parent) layout = QGridLayout() for i, output in enumerate(labels): layout.addWidget(QLabel(output), i, 0) combo = QComboBox() combo.addItems([ Slider, Spinner, ]) layout.addWidget(combo, i, 1) stack = QStackedWidget() horizontalSlider = QSlider() horizontalSlider.setOrientation(Qt.Horizontal) spinner = QSpinBox() spinner.valueChanged.connect(horizontalSlider.setValue) horizontalSlider.valueChanged.connect(spinner.setValue) stack.addWidget(horizontalSlider) stack.addWidget(spinner) combo.currentIndexChanged.connect(stack.setCurrentIndex) layout.addWidget(stack, i, 2) vertical_spacer = QSpacerItem(0, 0, QSizePolicy.Minimum, QSizePolicy.Expanding) layout.addItem(vertical_spacer, len(labels), 0, 1, 3) self.setLayout(layout) if __name__ == '__main__': import sys app = QApplication(sys.argv) ocw = TestWidget(['a', 'b', 'c', 'd', 'e']) ocw.show() sys.exit(app.exec_()) ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
[PyQt] need help with sizing QStackedWidgets
Here is a small example. I tried putting a vertical spacer on the bottom yet these stacked widgets want to take up space when resized. #!/usr/bin/env python from PyQt4.QtCore import * from PyQt4.QtGui import * class TestWidget(QWidget): def __init__(self, labels, parent=None): super(TestWidget, self).__init__(parent) layout = QGridLayout() for i, output in enumerate(labels): layout.addWidget(QLabel(output), i, 0) combo = QComboBox() combo.addItems([ Slider, Spinner, ]) layout.addWidget(combo, i, 1) stack = QStackedWidget() horizontalSlider = QSlider() horizontalSlider.setOrientation(Qt.Horizontal) spinner = QSpinBox() spinner.valueChanged.connect(horizontalSlider.setValue) horizontalSlider.valueChanged.connect(spinner.setValue) stack.addWidget(horizontalSlider) stack.addWidget(spinner) combo.currentIndexChanged.connect(stack.setCurrentIndex) layout.addWidget(stack, i, 2) vertical_spacer = QSpacerItem(0, 0, QSizePolicy.Minimum, QSizePolicy.Expanding) layout.addItem(vertical_spacer, len(labels), 0, 1, 3) self.setLayout(layout) if __name__ == '__main__': import sys app = QApplication(sys.argv) ocw = TestWidget(['a', 'b', 'c', 'd', 'e']) ocw.show() sys.exit(app.exec_()) ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
[PyQt] Absolute paths in qrc file.
I'm having trouble working with absolute file paths in my qrc resource file with PyQt. Am I doing something wrong or is it just something that rcc happens to support but not pyrcc4? Here is my resource file $ cat resources.qrc !DOCTYPE RCCRCC version=1.0 qresource file alias=filesaveas.png/usr/share/icons/oxygen/32x32/actions/document-save-as.png/file /qresource /RCC When I invoke pyrcc4: $ pyrcc4 -o qrc_resources.py resources.qrc Cannot find file: /usr/share/icons/oxygen/32x32/actions/document-save-as.png No resources in resource description. The file does exist: $ file /usr/share/icons/oxygen/32x32/actions/document-save-as.png /usr/share/icons/oxygen/32x32/actions/document-save-as.png: PNG image data, 32 x 32, 8-bit/color RGBA, non-interlaced Note: rcc works fine with this file: $ rcc resources.qrc -o resources.rcc $ wc -l resources.rcc 199 resources.rcc ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
Re: [PyQt] Absolute paths in qrc file.
Thanks, I think a symlink will work great. I'll just symlink to /usr/share/icons in my main directory. I'd love to be able to use QIcon.fromTheme but I'm on RHEL 6 it is unavailable. What is weird though is that it is available in Qt 4.6.2 but not PyQt 4.6.2 I thought that PyQt built bindings for whatever the Qt libs had available. Qt: 4.6.2 SIP: 4.9.3 PyQt: 4.6.2 Also, I found that putting a bunch of ../../../../ in front of the path worked too but that is obviously error-prone should your project be deep in a filesystem On Fri, Jun 28, 2013 at 12:08 PM, Baz Walter baz...@ftml.net wrote: On 28/06/13 15:45, Eric Frederich wrote: I'm having trouble working with absolute file paths in my qrc resource file with PyQt. Am I doing something wrong or is it just something that rcc happens to support but not pyrcc4? Here is my resource file $ cat resources.qrc !DOCTYPE RCCRCC version=1.0 qresource file alias=filesaveas.png/usr/share/icons/oxygen/32x32/actions/document-save-as.png/file /qresource /RCC When I invoke pyrcc4: $ pyrcc4 -o qrc_resources.py resources.qrc Cannot find file: /usr/share/icons/oxygen/32x32/actions/document-save-as.png No resources in resource description. The file does exist: $ file /usr/share/icons/oxygen/32x32/actions/document-save-as.png /usr/share/icons/oxygen/32x32/actions/document-save-as.png: PNG image data, 32 x 32, 8-bit/color RGBA, non-interlaced Note: rcc works fine with this file: $ rcc resources.qrc -o resources.rcc $ wc -l resources.rcc 199 resources.rcc Don't know about rcc, but the Qt docs are pretty clear that relative paths must be used in qrc files: https://qt-project.org/doc/qt-4.8/resources.html#resource-collection-files I suppose you could just use a symlink to work around this. PS: For standard icons, a possible alternative solution is to use QIcon.fromTheme (only really useful on Linux, though): https://qt-project.org/doc/qt-4.8/qicon.html#fromTheme -- Regards Baz Walter ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
Re: [PyQt] graphical file tail
Thanks David, This example works nicely. It's nice to find out what you did wrong, but I'm always open to new implementations. In fact that is what I wanted, was someone to do it their way so I could compare. I'm sure I was doing something terribly wrong but didn't want to post a do it for me email so I provided the implementation that I tried ;-) Thanks, ~Eric On Tue, Jun 25, 2013 at 8:22 AM, David Boddie david.bod...@met.no wrote: On Mon Jun 24 20:24:25 BST 2013, Eric Frederich wrote: I'm trying to tail several files graphically. I have been trying to find a way to tail several files in a GUI without much luck at all. [...] Basically, I want to graphically tail files and when the GUI closes the tail subprocesses are killed. Seems like a simple request, but I can't get it right. I notice that other messages have been talking about solving problems in your original implementation, but how about trying a different approach? The simple example below uses QProcess to show the output from a command. In this case, tail -f file. It will stop the process when the window is closed, but not the process creating the file, of course. David #!/usr/bin/env python import sys from PyQt4.QtCore import * from PyQt4.QtGui import * class TailWidget(QTextBrowser): def __init__(self, parent = None): QTextBrowser.__init__(self, parent) self.process = QProcess() self.process.readyReadStandardOutput.connect(self.addStdout) self.process.readyReadStandardError.connect(self.addStderr) self.process.finished.connect(self.stop) self.running = False def start(self, command, arguments): if self.running: return self.running = True self.process.start(command, arguments) def stop(self): self.running = False def addStdout(self): self.append(QString.fromLocal8Bit(self.process.readAllStandardOutput())) def addStderr(self): self.append(QString.fromLocal8Bit(self.process.readAllStandardError())) def closeEvent(self, event): if self.running: self.process.terminate() self.process.waitForFinished(1000) event.accept() if __name__ == __main__: app = QApplication(sys.argv) if len(app.arguments()) != 2: sys.stderr.write(Usage: %s file\n % app.arguments()[0]) sys.exit(1) w = TailWidget() w.start(tail, [-f, app.arguments()[1]]) w.show() sys.exit(app.exec_()) ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
[PyQt] graphical file tail
I'm trying to tail several files graphically. I have been trying to find a way to tail several files in a GUI without much luck at all. I get errors from tail saying broken pipe. I get PyQt errors saying underlying C++ objects have been destroyed. I get other Qt errors saying that threads are still running when the application exits etc The implementation posted below seems to suffer from the following errors. Not all the time. It depends. QThread: Destroyed while thread is still running QWaitCondition::wakeAll(): mutex lock failure: Please tell me what I'm doing wrong. Feel free to tell me if I'm doing something bone-headed. Basically, I want to graphically tail files and when the GUI closes the tail subprocesses are killed. Seems like a simple request, but I can't get it right. #!/usr/bin/env python from PyQt4.QtCore import * from PyQt4.QtGui import * import os from subprocess import Popen, PIPE class Tailer(QThread): def __init__(self, fname, parent=None): super(Tailer, self).__init__(parent) self.fname = fname self.connect(self, SIGNAL('finished()'), self.cleanup) def cleanup(self): print 'CLEANING UP' self.p.kill() print 'killed' def run(self): command = [tail, -f, self.fname] print command self.p = Popen(command, stdout=PIPE, stderr=PIPE) while True: line = self.p.stdout.readline() self.emit(SIGNAL('newline'), line.rstrip()) if not line: print 'BREAKING' break def foo(self): self.p.kill() class TailWidget(QWidget): def __init__(self, fnames, parent=None): super(TailWidget, self).__init__(parent) layout = QGridLayout() self.threads = {} self.browsers = {} for i, fname in enumerate(fnames): if not os.path.exists(fname): print fname, doesn't exist; creating p = Popen(['touch', fname], stdout=PIPE, stderr=PIPE) out, err = p.communicate() ret = p.wait() assert ret == 0 t = Tailer(fname, self) self.threads[fname] = t b = QTextBrowser() self.browsers[fname] = b layout.addWidget(QLabel('Tail on %s' % fname), 0, i) layout.addWidget(b, 1, i) self.connect(t, SIGNAL(newline), b.append) t.start() self.setLayout(layout) def closeEvent(self, event): for fname, t in self.threads.items(): t.foo() if __name__ == '__main__': import sys app = QApplication(sys.argv) tw = TailWidget(sys.argv[1:]) tw.show() sys.exit(app.exec_()) ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
Re: [PyQt] graphical file tail
Thanks for the suggestions. Unfortunately I do need to use Qt 4.6.2 from RHEL 6. This will also be on an NFS mounted drive. This is for a GUI that monitors the output of jobs run on Sun Grid Engine (SGE). So its not that the files _happen_ to be on NFS, it's actually _required_ that they are :-( Any Qt4 help would be appreciated. Am I cleaning up my tail processes correctly? Is it just the QThreads I'm screwing up? Are there other hidden dangers with my implementation? On Jun 24, 2013 7:25 PM, John Lee j...@pobox.com wrote: On Mon, 24 Jun 2013, Eric Frederich wrote: I'm trying to tail several files graphically. I have been trying to find a way to tail several files in a GUI without much luck at all. I get errors from tail saying broken pipe. I get PyQt errors saying underlying C++ objects have been destroyed. I get other Qt errors saying that threads are still running when the application exits etc The implementation posted below seems to suffer from the following errors. Not all the time. It depends. QThread: Destroyed while thread is still running QWaitCondition::wakeAll(): mutex lock failure: You're not calling .wait on the threads, and you probably want to give e.g. your QObjects a parent where you can, so that Qt manages the lifetime of the wrapped C++ objects (e.g. pass in self to the parent arg of the QTextBrowser constructor). But, I recommend doing it a different way: I find event-based code easier to think about than threads. So, if you can use Qt5, you might want to do away with the threads and the tail subprocess and replace them with QFileSystemWatcher. Use event-based code instead of the threads (I'm not talking about Qt events, I just mean hook up to the signals that that class emits and process a little input at a time so as to avoid blocking the UI, using QTimer where needed). I say Qt5 because Qt4 isn't very friendly to this way of working since it uses threads in the implementation of QFileSystemWatcher. Caveat: QFileSystemWatcher still has its problems, but the ones discussed at the URL below are more convenience issues than fundamental problems: I just found I had to experiment a bit to see when the different signals got emitted. http://blog.rburchell.com/**2012/03/qt-51-aka-when-** qfilesystemwatcher-might.htmlhttp://blog.rburchell.com/2012/03/qt-51-aka-when-qfilesystemwatcher-might.html Caveat #2: I imagine QFileSystemWatcher does not support filesystems like NFS, at least on Linux kernels with inotify support (but don't take my word for it, check the source). John __**_ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.**com/mailman/listinfo/pyqthttp://www.riverbankcomputing.com/mailman/listinfo/pyqt ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
[PyQt] Profiling with QThreads
Hello, I have a client application that does a long running data traversal making a lot of server calls. I put this operation in a QThread so that the GUI would stay responsive. I am now using a profiler on this application trying to see which calls to the server are taking most of the time. The problem here is that because its on a different thread the profiler doesn't pick up any of the calls. To get around this, on the QThread subclass I defined a method start_single like so... def start_single(self): self.emit(SIGNAL('started()')) self.run() self.emit(SIGNAL('finished()')) self.emit(SIGNAL('terminated()')) So when I replace the call to start with a call to start_single, I get the stuff I want in the profile. Is there a better way to accomplish the same thing? Am I missing something? ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
[PyQt] Help with unresponsive GUI
Hello all, I am having problems with an unresponsive GUI. I have a GUI for a client in a client / server program. For long running operations, I implemented a QThread subclass and do everything in the run method. Still, I have an unresponsive GUI. If I replace all the the server calls with a time.sleep, its still a long running process but the GUI is responsive. Why would server calls in a separate thread be different from sleep calls in a separate thread? Perhaps I am setting this up entirely wrong this is how I have things hooked up. The GUI Thread, when a button is pressed creates an instance of this QThread subclass. It connects the QThread subclass's finished signal to a slot called update_list. It then calls the start method. The QThread subclass traverses a big structure and stores results in an instance variable called data. So, when the thread is finished, the update_list slot is called and in there it gets results via self.sender().data If I'm doing something completely boneheaded, let me know. Thanks, ~Eric ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
Re: [PyQt] Help with unresponsive GUI
Bringing this topic back to the mailing list. I wish gmail had a more prominent reply to all button so I wouldn't inadvertently bring stuff offline. Problem solvedGIL is the problem. Cython made it somewhat simple to test especially since my Cython bindings are generated and not hand made. On each of my .pxd files I added nogil to the cdef extern from foo.h lines. e.g. ... cdef extern from foo.h nogil: int bar(char* x, int* y) And then each of my function calls in the .pyx files I put inside a with nogil cimport cfoo def bar(char* x): cdef int with nogil: cfoo.bar(x, y) return y After doing this my GUI is more responsive than ever. This is my first gripe with the GIL and I have done used the multiprocessing module before with work queues. Weird. Thanks for the help. On Tue, Aug 30, 2011 at 11:26 AM, Eric Frederich eric.freder...@gmail.com wrote: From what I can tell, the worker thread is not eating resources. This particular system has 12 cores and 24GB of RAM. Other GUI's on the same system are very responsive. Perhaps it is a GIL issue. I created Cython bindings to a 3rd party lib. In my bindings I do nothing with the GIL. I just happened to look at this http://docs.python.org/c-api/init.html#releasing-the-gil-from-extension-code I will try to release and re-acquire in my bindings and see if this fixes things. Thanks, ~Eric On Tue, Aug 30, 2011 at 11:07 AM, Erik Janssens erik.janss...@conceptive.be wrote: when calling time.sleep, all resources are given explicitly to the other threads. two things might go wrong : - the worker thread is eating all resources of the machine - the worker thread keeps the GIL locked for a very long time (maybe a third party lib that does not release the GIL properly) On Tue, 2011-08-30 at 10:47 -0400, Eric Frederich wrote: Hello all, I am having problems with an unresponsive GUI. I have a GUI for a client in a client / server program. For long running operations, I implemented a QThread subclass and do everything in the run method. Still, I have an unresponsive GUI. If I replace all the the server calls with a time.sleep, its still a long running process but the GUI is responsive..amount_to_deduce Why would server calls in a separate thread be different from sleep calls in a separate thread? Perhaps I am setting this up entirely wrong this is how I have things hooked up. The GUI Thread, when a button is pressed creates an instance of this QThread subclass. It connects the QThread subclass's finished signal to a slot called update_list. It then calls the start method. The QThread subclass traverses a big structure and stores results in an instance variable called data. So, when the thread is finished, the update_list slot is called and in there it gets results via self.sender().data If I'm doing something completely boneheaded, let me know. Thanks, ~Eric ___ PyQt mailing list PyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
Re: [PyQt] Help with Login Dialog / QThread issues
I'm just a little confused on what connections to make. I'm sure I could get something working but I'd be going about it the wrong way. Forget my original post. This is what I want. I want a login dialog with username, password and group. I want that dialog to stay up until the login is successful or user hits cancel. I have a QThread subclass for logging in. It emits either success or fail, and with fail it provides some text feedback. When the login thread starts a progress bar should start animating. This is where I am completely lost as far as connections go. The QDialogButtonBox has accepted, rejected. The QDialog has accepted, rejected. My login thread has success, and fail. There are clicked() signals as well. Its not complicated, but I'm new to Qt and PyQt. I think I need someone to spell it out for me. Thanks, ~Eric On Sat, Aug 6, 2011 at 1:14 PM, Baz Walter baz...@ftml.net wrote: On 05/08/11 17:46, Eric Frederich wrote: Any takers? On Thu, Jul 7, 2011 at 12:38 PM, Eric Frederich eric.freder...@gmail.com wrote: Hello, I am trying to create a login dialog for my application. Logging in can take a couple of seconds so I wanted to show a progress bar during the login process. I think that for my QProgressBar to animate during this time, I need to log in on a different thread. Is this true? So, below I have what I think is a working example. Is there a better way to call QDialog's accept slot when the login thread is finished than how I am doing it via functools.partial? It seems a bit hacky. from functools import partial class LoginThread(QThread): def __init__(self, username, password, parent=None): super(LoginThread, self).__init__(parent) self.username = username self.password = password def run(self): LOGIN( self.username, self.password, ) class LoginDialog(QDialog, Ui_LoginDialog): def __init__(self, *args, **kwargs): super(LoginDialog, self).__init__(*args, **kwargs) self.setupUi(self) self.progressbar.hide() def accept(self): self.progressbar.setMinimum(0) self.progressbar.setMaximum(0) self.progressbar.show() self.lt = LoginThread( str(self.username_edit.text()), str(self.password_edit.text()) ) self.connect(self.lt, SIGNAL('finished()'), partial(QDialog.accept, self)) self.lt.start() it's hard to tell from the limited code you've posted why you need to override accept(). why not just create a handler for the clicked() signal of the ok button (or whatever it is) and then connect the thread's finished() signal directly to the dialog's accept() slot? ___ PyQt mailing list PyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
Re: [PyQt] Help with Login Dialog / QThread issues
Any takers? On Thu, Jul 7, 2011 at 12:38 PM, Eric Frederich eric.freder...@gmail.com wrote: Hello, I am trying to create a login dialog for my application. Logging in can take a couple of seconds so I wanted to show a progress bar during the login process. I think that for my QProgressBar to animate during this time, I need to log in on a different thread. Is this true? So, below I have what I think is a working example. Is there a better way to call QDialog's accept slot when the login thread is finished than how I am doing it via functools.partial? It seems a bit hacky. from functools import partial class LoginThread(QThread): def __init__(self, username, password, parent=None): super(LoginThread, self).__init__(parent) self.username = username self.password = password def run(self): LOGIN( self.username, self.password, ) class LoginDialog(QDialog, Ui_LoginDialog): def __init__(self, *args, **kwargs): super(LoginDialog, self).__init__(*args, **kwargs) self.setupUi(self) self.progressbar.hide() def accept(self): self.progressbar.setMinimum(0) self.progressbar.setMaximum(0) self.progressbar.show() self.lt = LoginThread( str(self.username_edit.text()), str(self.password_edit.text()) ) self.connect(self.lt, SIGNAL('finished()'), partial(QDialog.accept, self)) self.lt.start() ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
[PyQt] Help with Login Dialog / QThread issues
Hello, I am trying to create a login dialog for my application. Logging in can take a couple of seconds so I wanted to show a progress bar during the login process. I think that for my QProgressBar to animate during this time, I need to log in on a different thread. Is this true? So, below I have what I think is a working example. Is there a better way to call QDialog's accept slot when the login thread is finished than how I am doing it via functools.partial? It seems a bit hacky. from functools import partial class LoginThread(QThread): def __init__(self, username, password, parent=None): super(LoginThread, self).__init__(parent) self.username = username self.password = password def run(self): LOGIN( self.username, self.password, ) class LoginDialog(QDialog, Ui_LoginDialog): def __init__(self, *args, **kwargs): super(LoginDialog, self).__init__(*args, **kwargs) self.setupUi(self) self.progressbar.hide() def accept(self): self.progressbar.setMinimum(0) self.progressbar.setMaximum(0) self.progressbar.show() self.lt = LoginThread( str(self.username_edit.text()), str(self.password_edit.text()) ) self.connect(self.lt, SIGNAL('finished()'), partial(QDialog.accept, self)) self.lt.start() ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
[PyQt] Model / View for some data
Hello, I have some data that I would like to be displayed somehow. I have a bunch of parent / child relationships. These relationships can form loops. Also, children can have multiple parents. Can this be put into a tree view? I have ran into problems trying to do this via AbstractItemModel because of the parent method. Any tips / suggestions? Thanks, ~Eric ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
[PyQt] QPainter::end: Painter ended with 2 saved states
I was trying to get an example working with a QThread. I wound up creating one but after running it for a while and pressing buttons I got the error... QPainter::end: Painter ended with 2 saved states Am I doing something wrong? I wanted an example where a worker thread would query a database or some other long running operation and leave the GUI responsive (although disabling certain elements like the button it was launched from). This is the code I was running from PyQt4.QtCore import * from PyQt4.QtGui import * class Blah(QThread): def __init__(self, parent=None): super(Blah, self).__init__(parent) print 'new thread created' def run(self): print 'running' self.parent().setEnabled(False) import time for i in xrange(10): self.parent().setText(%02d % i) time.sleep(.1) self.parent().setText(Push Me) self.parent().setEnabled(True) def say_hi(): print 'HELLO' class MyDialog(QDialog): def __init__(self, *args, **kwargs): super(MyDialog, self).__init__(*args, **kwargs) self.setWindowTitle(Hey, hows it going?) layout = QHBoxLayout() self.buttons = [] for i in xrange(5): button = QPushButton(Push Me) self.buttons.append(button) blah = Blah(button) self.connect(button, SIGNAL(pressed()), blah.start) layout.addWidget(button) self.setLayout(layout) if __name__ == '__main__': import sys app = QApplication(sys.argv[1:]) md = MyDialog() md.show() sys.exit(app.exec_()) ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
Re: [PyQt] QPainter::end: Painter ended with 2 saved states
Here is a reworked example. Do you see any potential problems with this one? Is the call to setText okay? Is it okay to access the data member the way I'm doing it in print_data? Thanks, ~Eric from PyQt4.QtCore import * from PyQt4.QtGui import * class Blah(QThread): def __init__(self, parent=None): super(Blah, self).__init__(parent) self.data = [] def run(self): import time for i in xrange(10): time.sleep(.1) txt = '%02d' % i self.emit(SIGNAL('SLEPT'), txt) self.data.append(txt) self.emit(SIGNAL(ALLDONE)) from functools import partial class MyDialog(QDialog): def __init__(self, *args, **kwargs): super(MyDialog, self).__init__(*args, **kwargs) self.setWindowTitle(Hey, hows it going?) layout = QVBoxLayout() for i in xrange(15): button = QPushButton(Push Me, self) self.connect(button, SIGNAL(pressed()), self.do_something) layout.addWidget(button) self.setLayout(layout) def do_something(self): self.sender().setEnabled(False) b = Blah(self) self.connect(b, SIGNAL('ALLDONE'), partial(self.sender().setText, Push Me)) self.connect(b, SIGNAL('ALLDONE'), partial(self.print_data, b)) self.connect(b, SIGNAL('ALLDONE'), partial(self.sender().setEnabled, True)) self.connect(b, SIGNAL('SLEPT'), self.sender().setText) b.start() def print_data(self, blah): print blah.data if __name__ == '__main__': import sys app = QApplication(sys.argv[1:]) md = MyDialog() md.show() sys.exit(app.exec_()) On Tue, Jun 28, 2011 at 3:05 PM, Hans-Peter Jansen h...@urpla.net wrote: On Tuesday 28 June 2011, 20:52:12 Eric Frederich wrote: I was trying to get an example working with a QThread. I wound up creating one but after running it for a while and pressing buttons I got the error... QPainter::end: Painter ended with 2 saved states Am I doing something wrong? I wanted an example where a worker thread would query a database or some other long running operation and leave the GUI responsive (although disabling certain elements like the button it was launched from). This is the code I was running from PyQt4.QtCore import * from PyQt4.QtGui import * class Blah(QThread): def __init__(self, parent=None): super(Blah, self).__init__(parent) print 'new thread created' def run(self): print 'running' self.parent().setEnabled(False) import time for i in xrange(10): self.parent().setText(%02d % i) time.sleep(.1) self.parent().setText(Push Me) self.parent().setEnabled(True) You're doing bad things here, that you shouldn't do from a thread, e.g. using methods, that trigger redraws. You should create signals in your thread, that signals operations to the main thread, where you would actually process these operations without fear. Pete ___ PyQt mailing list PyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
Re: [PyQt] Kudos
Is there a PyQt installer built with Visual Studio? I am embedding a Python interpreter in a 3rd party application and creating bindings to that same 3rd party's libraries. Unless I am mistaken I am fairly sure that I need both Python and my bindings created using Visual Studio. I have tried to use a Python from a binary installer and was unable to import my bindings as I got DLL import errors. So, since I have gone down this route I have to manually build anything else I want available in my Python installation such as PyQT. Fortunately there was an installer for Qt built with Visual Studio. If I don't need to be doing all of this please let me know, but I at least need to build my own bindings to the 3rd party libraries using Visual Studio. On Apr 20, 2011 3:15 AM, Phil Thompson p...@riverbankcomputing.com wrote: ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
[PyQt] Kudos
Hey Phil, I recently built some Python bindings (using Cython) for a 3rd party library that had to be built using Visual Studio 2005. Its great having these bindings and being able to use Python. Unfortunately, to install any other Python modules I have to build them myself as nobody offers versions using Visual Studio. When I wanted to start using Qt from Python I initially chose PySide for its more liberal license and because as of their 1.0 release they had Windows support. Building it was an absolute pain. I had to fix some scripts here and there. The resulting install didn't even have uic and I was instructed to copy it from the official binary release of the PySide Windows installer. After doing this it wouldn't compile my .ui files and just error out. I compiled the .ui files using the PyQt pyuic4 and got PySide to work okay. Because of all those problems I decided to give PyQt a go on Windows. Sip installed no problem. PyQt gave me some trouble using configure.py because I had a space the path of the source directory that I was running configure from. After moving it to a more boring C:\PyQt-win-gpl-4.8.3 it installed just fine. I wound up having a problem with pyuic4 also just like I did with PySide. I dug into it a bit and it was a case of me not having built the pyexpat module. After building it and putting pyexpat.pyd in the DLLs folder pyuic4 worked just fine. Makes me wonder if thats what PySide was missing as well. In any case, for now I'll be using PyQt. One thing that PySide did nice that PyQt didn't do was get the Qt dll files copied into the the Python installation so that everything was self contained. It would be nice not to have to have end user's of my programs have to do a full Qt install when they'll only be using it from PyQt. Anyway, just wanted to say kudos to having a relatively pain free installation experience on Windows (with Visual Studio 2005 anyway) compared to the competition. Thanks, ~Eric ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
[PyQt] long running operations
I'd like to be able to do something in PyQt that I know how to do in Java / Swing and that is run certain processes off of the EDT (event dispatch thread). Normally, I lock down different parts of the gui before hand, and then re-enable them after the operation is done. This must be possible in PyQt but I'm looking for someone to point me in the right direction. Does Qt have support for this type of stuff, and then which should I use to do it Python or Qt? Any help is appreciated. Thanks, ~Eric ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
[PyQt] Translating from a function
I have a bunch of helper functions that raise exceptions and I'd like the messages in those exceptions to be translated. How should I get those strings translated? QObject.tr is not a static method, I can't just call it. I need a QObject don't I? What is the best practice here? Thanks, ~Eric ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
[PyQt] signal propagating
Hello, Here's a stripped down example of my problem. I have a group of widgets that I keep together with a class called MyWidgetGroup. It holds a line edit and a label which together have a meaning (getMeaning) but by themselves mean nothing. I need to make connections to a method so it'll get called whenever the widget's text changes but I don't want the reference to the line edit, I want the reference to the widget group (so I can getMeaning on it). To do this I wound up creating a dummy method that just propagates the signal so that it comes from the widget group instead of just the line edit. I have a bad feeling about this. There must be a better way to do this right? Can this be accomplished by connecting signals to signals? class MyWidgetGroup(QWidget): def __init__(self, parent=None): super(MyWidgetGroup, self).__init__(parent) self.myLabel = MyLabel(self) self.myEdit = MyLineEdit(self) self.connect(self.myEdit, SIGNAL(textChanged(QString)), self.pointless) def pointless(self, qstring): self.emit(SIGNAL(theValueChanged)) def getMeaning(self): return self.myLabel.text() + '-' + self.myEdit.text() ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
[PyQt] synced line edits
I'm having some trouble trying to figure out how to get two line edits to constantly be in sync including cursor position. I'm sure its simple, or a matter of creating the right connections, but I can't seem to figure it out. I'm hooking two line edits textChagned signal up to the other's setText slot. Thankfully PyQt (or Qt)'s setText is smart enough to check whether the text actually changed before emitting another signal and not getting stuck in an infinite loop. The problem seems to be that setText on a QLineEdit doesn't do a similar check before changing the cursor position. I'd like to get two line edits synced up so that I can insert text in the beginning, middle, or end of the string but after any letter gets typed the cursor goes to the end of the string. Any help is appreciated. Thanks, ~Eric #!/usr/bin/env python from PyQt4.QtCore import * from PyQt4.QtGui import * class MyForm(QDialog): def __init__(self, parent=None): super(MyForm, self).__init__(parent) layout = QVBoxLayout() le1 = QLineEdit() le2 = QLineEdit() layout.addWidget(le1) layout.addWidget(le2) self.setLayout(layout) self.connect(le1, SIGNAL(textChanged(QString)), le2.setText) self.connect(le2, SIGNAL(textChanged(QString)), le1.setText) if __name__ == '__main__': import sys app = QApplication(sys.argv) mf = MyForm() mf.show() sys.exit(app.exec_()) ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
[PyQt] Newbie QMainWindow tips
Trying to get my first PyQt MainWindow application going. Its going to be to edit multiple [we'll just call them] documents in tabs. I will have several dockwidgets that need to correspond to the currently selected tab. So when the tab changes, or the data within the document changes, several dockwidgets need to be kept in sync. Some questions. 1) How do I create static members for these dockwidgets on my subclass of QMainWindow? I'd like to do this so I don't have to pass around the actual reference to an instance of the subclass (just import MyMainWindow at the top and get it using MyMainWindow.dockWidgetX). Right now I'm creating them during __init__ of my QMainWindow subclass and they actually take references to other instance objects but I can re-factor it to get those things later on. Is having static members an advisable thing to do? If not, please tell me a better way to do it. Passing around instances of the main window seems like its wrong to me, but again, I'm a newbie. 2) What is a good strategy for keeping the dock widgets in sync? Thanks, ~Eric ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
Re: [PyQt] Newbie QMainWindow tips
On Thu, Sep 16, 2010 at 11:55 AM, fpp fpp@gmail.com wrote: On Thu, Sep 16, 2010 at 5:02 PM, Eric Frederich eric.freder...@gmail.com wrote: Trying to get my first PyQt MainWindow application going. Its going to be to edit multiple [we'll just call them] documents in tabs. I will have several dockwidgets that need to correspond to the currently selected tab. So when the tab changes, or the data within the document changes, several dockwidgets need to be kept in sync. Some questions. 1) How do I create static members for these dockwidgets on my subclass of QMainWindow? I'd like to do this so I don't have to pass around the actual reference to an instance of the subclass (just import MyMainWindow at the top and get it using MyMainWindow.dockWidgetX). Right now I'm creating them during __init__ of my QMainWindow subclass and they actually take references to other instance objects but I can re-factor it to get those things later on. Is having static members an advisable thing to do? If not, please tell me a better way to do it. Passing around instances of the main window seems like its wrong to me, but again, I'm a newbie. I'm not sure I understand this one correctly, but if you create your project with eric4 (and thus design your UI with Qt Designer), that is exactly the result you will get, so it's probably good practice... 2) What is a good strategy for keeping the dock widgets in sync? The standard Qt way is to connect the signal emitted by the tab bar when you change tabs, to a slot (method) in your dock widgets so they will update their contents accordingly. fpp, you didn't 'reply to all' Since I'm replying to you I'm bringing the discussion back to the mailing list. In regard to question 2) So if I connect the tab bar's currentChanged(int) signal to a dock widget's method, where does the dock widget get the data from? Would the dock widget instance need to have a pointer to the the tab widget or to something else? This is what I'm confused about. ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
Re: [PyQt] Newbie QMainWindow tips
On Thu, Sep 16, 2010 at 1:27 PM, fpp fpp@gmail.com wrote: On Thu, Sep 16, 2010 at 7:24 PM, Eric Frederich eric.freder...@gmail.com wrote: So if I connect the tab bar's currentChanged(int) signal to a dock widget's method, where does the dock widget get the data from? Would the dock widget instance need to have a pointer to the the tab widget or to something else? This is what I'm confused about. There is always a way :-) Easiest here is for the dockwidget to query the tabwidget for its current index (active tab), there is a method for that. I think that seems to be my problem. Just way too many ways to skin this cat. I'd hate to say something good about Java (especially now that they're owned by Orable) but there were much less options for me to get overwhelmed with. Perhaps after I'm done being overwhelmed I'll welcome the multitude of options. Its just at this early stage I don't want to start going down the wrong path. ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
[PyQt] Weird problem with QSystemTrayIcon
I looked at the example with PyQt for system tray icons and tried to use it in my application. I couldn't get it to work. I couldn't find what the example was doing that I wasn't doing. I even did the stuff in the same order. I wound up taking the example and in-lining a bunch of functions then bit by bit removing things until I got a minimalistic system tray icon program. In the end, I wound up with a small sample application where for some reason I need to call QtGui.QGroupBox() with some string or I'll never see the system tray icon. Below is example code. If you remove the line ... self.WHY_DO_I_NEED_TO_DO_THIS = QtGui.QGroupBox(A) ... then I don't see any system tray icon. Can anyone else verify this? I'm on Linux 64 bit with Python 2.6.5 and PyQt 4.7.2. Thanks, ~Eric #!/usr/bin/env python from PyQt4 import QtCore, QtGui class Window(QtGui.QDialog): def __init__(self): super(Window, self).__init__() self.WHY_DO_I_NEED_TO_DO_THIS = QtGui.QGroupBox(A) self.restoreAction = QtGui.QAction(Restore, self, triggered=self.showNormal) self.quitAction = QtGui.QAction(Quit, self, triggered=QtGui.qApp.quit) self.trayIconMenu = QtGui.QMenu(self) self.trayIconMenu.addAction(self.restoreAction) self.trayIconMenu.addSeparator() self.trayIconMenu.addAction(self.quitAction) self.trayIcon = QtGui.QSystemTrayIcon(self) self.trayIcon.setContextMenu(self.trayIconMenu) self.trayIcon.setIcon(QtGui.QIcon(./logo.png)) mainLayout = QtGui.QVBoxLayout() mainLayout.addWidget(QtGui.QPushButton(Help Please)) self.setLayout(mainLayout) self.trayIcon.show() self.setWindowTitle(Systray) self.resize(400, 300) if __name__ == '__main__': import sys app = QtGui.QApplication(sys.argv) if not QtGui.QSystemTrayIcon.isSystemTrayAvailable(): QtGui.QMessageBox.critical(None, Systray, I couldn't detect any system tray on this system.) sys.exit(1) #QtGui.QApplication.setQuitOnLastWindowClosed(False) window = Window() window.show() sys.exit(app.exec_()) ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
[PyQt] connections vs. instance variables
I constantly find myself with options like... a) create a connection from foo's custom signal to bar's slot or b) when creating the foo object, give it a reference to bar, and instead of emitting a custom signal, just call bar's slot directly. What is more lightweight an instance variable or a connection? I'm sure this must be common. Are there guidelines to use, rules of thumb etc? Thanks, ~Eric ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
[PyQt] events / signals
If I find myself subclassing a widget just to get something to happen on an event am I doing something wrong? Is there another way to accomplish this? Is there a way to use an event like a signal in a self.connect? For example... If I want so do something when a label is clicked I have done the following and then just connect to the signal I emmit. class ClickableLabel(QLabel): def __init__(self, *args, **kwargs): super(ClickableLabel, self).__init__(*args, **kwargs) def mousePressEvent(self, event): self.emit(SIGNAL(clicked)) Thanks, ~Eric ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
Re: [PyQt] QValidator.validate() returns TypeError: invalid result type
Whoops, didn't realize I took this conversation off the mailing list. So, does this mean it is not possible then to have a validator in Python2 fix the string? On Sat, Aug 14, 2010 at 7:12 AM, Phil Thompson p...@riverbankcomputing.comwrote: On Fri, 6 Aug 2010 14:57:45 -0400, Eric Frederich eric.freder...@gmail.com wrote: The help only lists the (QVlidator.State, int)... it does not list the one that returns a new string. Does this mean it is not possible? I get the same docstring for QValidator.validate when I call sip.setapi('QString', 1) or sip.setapi('QString', 2) This is what I get Help on built-in function validate: validate(...) QValidator.validate(QString, int) - (QValidator.State, int) The docstring doesn't get changed when you set the API version. It is correct for the default API for the particular version of Python you are using (v1 for Python2 and v2 for Python3). Phil ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
[PyQt] QValidator.validate() returns TypeError: invalid result type
Reading the documentation here... http://www.riverbankcomputing.co.uk/static/Docs/PyQt4/html/qvalidator.html ... I see that the validate() function is listed twice. One returning (State, QString, int) and another returning just (State, int) I would think this means I have the choice to return either 2-tuple or a 3-tuple. Returning a 2-tuple seems to work fine but I get an error trying to return (State, QString, and int) Is this a bug, or did I miss something or interpret the documentation wrong? Code is below. As a side note... I have tried sending this twice before but it never got through to where I could read it in the archives. Perhaps I need to be subscribed to the list to post to it??? If so it doesn't say that on the mailing list web page. Thanks, ~Eric #!/usr/bin/env python import sys from PyQt4.QtCore import * from PyQt4.QtGui import * class EricsValidator(QValidator): def validate(self, text, position): print 'validate (%s %s)' % (repr(text), repr(position)) return (QValidator.Intermediate, text, position) class Form(QDialog): def __init__(self, parent=None): super(Form, self).__init__(parent) self.lineedit = QLineEdit() self.validators = [] layout = QGridLayout() layout.addWidget(self.lineedit, 0, 0, 1, 2) for i, (name, validator) in enumerate([ (QIntValidator , QIntValidator(self) ), (QDoubleValidator, QDoubleValidator(self)), (Eric's Validator, EricsValidator(self) ), ]): label = QLabel(name) button = QRadioButton() label.setBuddy(button) self.validators.append((validator, label, button)) layout.addWidget(label , i + 1, 0) layout.addWidget(button, i + 1, 1) label.setBuddy(button) self.connect(button, SIGNAL(clicked()), self.update) self.validators[-1][2].setChecked(True) self.setLayout(layout) self.setWindowTitle(Validation Tester) self.update() def update(self): for validator, label, button in self.validators: if button.isChecked(): print 'setting validator to', label.text() self.lineedit.setValidator(validator) break if __name__ == '__main__': app = QApplication(sys.argv) form = Form() form.show() app.exec_() ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt