From frank at ohufx.com Wed Dec 4 22:54:29 2013 From: frank at ohufx.com (Frank Rueter | OHUfx) Date: Thu, 05 Dec 2013 10:54:29 +1300 Subject: [PySide] how to control tab focus between QAction and QWidgetAction's children? Message-ID: <529FA495.5060000@ohufx.com> Hi all, I am struggling to control the focus shift (via the tab key) inside a QMenu. The menu has one QAction and one QWidgetAction. The latter has three child widgets (two QLineEdit and one QPushButton widget). When the cursor is inside of one of the child widgets, the tab key does not work as expected to move to the next child widget, instead the QMenu takes ownership of the key stroke and shifts focus to the QAction. How can I make the QWidgetAction take precedence over the QMenu when the tab key is hit? I also posted this on SO yesterday with example code but so far no workable solutions: http://stackoverflow.com/questions/20365663/how-to-control-focus-of-qwidgetactions-child-widgets/20366913?iemail=1&noredirect=1#20366913 Cheers, frank From frank at ohufx.com Thu Dec 5 20:51:55 2013 From: frank at ohufx.com (Frank Rueter | OHUfx) Date: Fri, 06 Dec 2013 08:51:55 +1300 Subject: [PySide] how to control tab focus between QAction and QWidgetAction's children? In-Reply-To: <529FA495.5060000@ohufx.com> References: <529FA495.5060000@ohufx.com> Message-ID: <52A0D95B.3010802@ohufx.com> looks like the re-implementing the QMenu's virtual function focusNextPrevChild() to behave like in a standard QWidget is the winner here (see SO for details) On 05/12/13 10:54, Frank Rueter | OHUfx wrote: > Hi all, > > I am struggling to control the focus shift (via the tab key) inside a > QMenu. The menu has one QAction and one QWidgetAction. The latter has > three child widgets (two QLineEdit and one QPushButton widget). > When the cursor is inside of one of the child widgets, the tab key does > not work as expected to move to the next child widget, instead the QMenu > takes ownership of the key stroke and shifts focus to the QAction. > > How can I make the QWidgetAction take precedence over the QMenu when the > tab key is hit? > > I also posted this on SO yesterday with example code but so far no > workable solutions: > > http://stackoverflow.com/questions/20365663/how-to-control-focus-of-qwidgetactions-child-widgets/20366913?iemail=1&noredirect=1#20366913 > > > Cheers, > frank > > > _______________________________________________ > PySide mailing list > PySide at qt-project.org > http://lists.qt-project.org/mailman/listinfo/pyside From nicolas.saubat at imag.fr Mon Dec 9 12:25:09 2013 From: nicolas.saubat at imag.fr (Nicolas SAUBAT) Date: Mon, 09 Dec 2013 12:25:09 +0100 Subject: [PySide] Shiboken generation error : Minimal constructor for type 'Array' In-Reply-To: <528A52AA.7090903@imag.fr> References: <528A52AA.7090903@imag.fr> Message-ID: <52A5A895.1090302@imag.fr> An HTML attachment was scrubbed... URL: From nicolas.saubat at imag.fr Mon Dec 9 16:59:08 2013 From: nicolas.saubat at imag.fr (Nicolas SAUBAT) Date: Mon, 09 Dec 2013 16:59:08 +0100 Subject: [PySide] PySide 1.2.1 API Docs In-Reply-To: References: Message-ID: <52A5E8CC.2050200@imag.fr> An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: api_extractor.pdf Type: application/pdf Size: 133163 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: shiboken.pdf Type: application/pdf Size: 401348 bytes Desc: not available URL: From sean at seanfisk.com Tue Dec 10 03:45:49 2013 From: sean at seanfisk.com (Sean Fisk) Date: Mon, 9 Dec 2013 21:45:49 -0500 Subject: [PySide] PySide 1.2.1 API Docs In-Reply-To: <52A5E8CC.2050200@imag.fr> References: <52A5E8CC.2050200@imag.fr> Message-ID: Hi Nicolas, I’d be happy to modify the script to create the API Extractor documentation! There are two scripts in my Github repository- one to build the docs and the other to generate tarballs. Can you fork my repo , make the modifications, and create a pull request? Then I’ll run the scripts again and upload the results to my Github pages. If it's easier, you can just send a patch. - Sean -- Sean Fisk On Mon, Dec 9, 2013 at 10:59 AM, Nicolas SAUBAT wrote: > Hi, > > Thank you Sean for your work regarding the documentation. > A few weeks ago, I was also looking for documentation regarding Shiboken > (as a beginner I needed to start with some basic documentation). > I wasn't aware of your email, this is why I also used the sources to build > the Shiboken 1.2.1 documentation (not PySide API docs, at least for the > moment). > But, I noticed the API-Extractor documentation was not built, thus I > modified the CMake configuration files in order to build it. > Might it be interesting to add the missing API-Extractor documentation to > your script / personnal page ? > > Anyway, I built the documentation as PDF files. I attached them, hoping > they might help someone. > > Thanks, > Nicolas. > > > > On 11/26/2013 08:12 PM, Sean Fisk wrote: > > Thanks, Anand, for testing the script out. Glad to have some confirmation > of it working. > > Thanks, Roman, for uploading to ReadTheDocs and for your advice on > building the docs. > > > -- > Sean Fisk > > > On Tue, Nov 26, 2013 at 5:34 AM, Gadiyar, Anand wrote: > >> Sean, >> >> >> >> Thanks for this. I’ve just used your script on an Ubuntu box and it works >> well! >> >> >> >> - Anand >> >> >> >> *From:* pyside-bounces+gadiyar=ti.com at qt-project.org [mailto: >> pyside-bounces+gadiyar=ti.com at qt-project.org] *On Behalf Of *Roman Lacko >> *Sent:* Tuesday, November 26, 2013 1:58 PM >> *To:* Sean Fisk >> *Cc:* PySide >> *Subject:* Re: [PySide] PySide 1.2.1 API Docs >> >> >> >> Hi Sean, >> >> thanks for the hard work you spend on this. >> >> I will upload the docs to readthedocs server. >> >> Thanks >> >> Roman >> >> >> >> 2013/11/26 Sean Fisk >> >> Hello PySiders! >> >> After a monumental struggle I was able to achieve the goal of building >> the PySide and Shiboken 1.2.1 API docs. Following in the footsteps of those >> before me, I’ve uploaded them to Github Pagesfor use by the community. I’ve also created tarballs of the documentation >> available for download. >> >> I’ve gathered the build process into a Bash script which is available in this >> Github repo . I’ve tested it on >> Mac OS X and CentOS, and it should work on most UNIX-like systems. If >> anyone wants to hack on it, let me know if you have questions. >> >> During the build process, I stumbled upon a couple things: >> >> · qdoc3 from Qt 4.6 is needed to build API docs for PySide. This >> is because WebXML support was buggy in Qt 4.7 and dropped in Qt 4.8, and >> Shiboken uses this to generate the docs (thanks Roman Lacko). This is very >> annoying because parts of Qt 4.6 must be configured and built for qdoc3to build correctly. >> >> · Shiboken has a documented --documentation-only flag but >> refuses to actually accept it. But Shiboken doesn’t tell you which option >> was invalid, only that it was “called with the wrong arguments.” This is >> annoying but seems like it has an easy fix. >> >> The documentation build process is little convoluted in general. Some of >> these issues seem like they are out of the hands of PySide, though. >> >> I hope these docs are able to help somebody out there! >> >> Thanks, >> >> -- >> >> Sean Fisk >> >> >> _______________________________________________ >> PySide mailing list >> PySide at qt-project.org >> http://lists.qt-project.org/mailman/listinfo/pyside >> >> >> > > > > _______________________________________________ > PySide mailing listPySide at qt-project.orghttp://lists.qt-project.org/mailman/listinfo/pyside > > > -- > Nicolas SAUBAT > Ingénieur Recherche et Développement > Equipe GMCAO - Laboratoire TIMC-IMAG > Pavillon Taillefer > Allée des Alpes - Domaine de la Merci > 38706 La Tronche > Tel : (33)04 56 52 00 10 > > > _______________________________________________ > PySide mailing list > PySide at qt-project.org > http://lists.qt-project.org/mailman/listinfo/pyside > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jwevandijk at xs4all.nl Tue Dec 10 21:17:14 2013 From: jwevandijk at xs4all.nl (Janwillem van Dijk) Date: Tue, 10 Dec 2013 21:17:14 +0100 Subject: [PySide] wait for QFileDialog to close Message-ID: <52A776CA.60704@xs4all.nl> Hi, I have a PySide script that uses QFileDialog.getExistingDirectory(). After clicking the Open button the script proceeds with a lengthy part that processes a files list and writes to a QPlainTextEdit. Unfortunately the QFileDialog widget does only disappear after this processing is finished, hiding the QPlainTextEdit. How can I make that the QFileDialog widget is gone before the processing starts? Cheers, Janwillem -------------- next part -------------- An HTML attachment was scrubbed... URL: From sean at seanfisk.com Tue Dec 10 21:35:24 2013 From: sean at seanfisk.com (Sean Fisk) Date: Tue, 10 Dec 2013 15:35:24 -0500 Subject: [PySide] wait for QFileDialog to close In-Reply-To: <52A776CA.60704@xs4all.nl> References: <52A776CA.60704@xs4all.nl> Message-ID: Hi Janwillem, Are you running the “lengthy part that processes a files list” within the GUI thread? If so, you will probably see your GUI hang while this is happening (you won’t be able to click or do anything). In this case, you should consider running the processing in a different thread using QThreador QThreadPool . Can you post the relevant part of the code? Thanks, -- Sean Fisk On Tue, Dec 10, 2013 at 3:17 PM, Janwillem van Dijk wrote: > Hi, I have a PySide script that uses QFileDialog.getExistingDirectory(). > After clicking the Open button the script proceeds with a lengthy part that > processes a files list and writes to a QPlainTextEdit. Unfortunately the > QFileDialog widget does only disappear after this processing is finished, > hiding the QPlainTextEdit. > > How can I make that the QFileDialog widget is gone before the processing > starts? > > Cheers, Janwillem > > > > > _______________________________________________ > PySide mailing list > PySide at qt-project.org > http://lists.qt-project.org/mailman/listinfo/pyside > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From frank at ohufx.com Tue Dec 10 21:32:16 2013 From: frank at ohufx.com (Frank Rueter | OHUfx) Date: Wed, 11 Dec 2013 09:32:16 +1300 Subject: [PySide] wait for QFileDialog to close In-Reply-To: <52A776CA.60704@xs4all.nl> References: <52A776CA.60704@xs4all.nl> Message-ID: <52A77A50.8050504@ohufx.com> I'm not quite clear on what you are doing, but can you use the QDialog's signals to trigger the file processing only after the dialog has finished it's purpose? I.e. QDialog.finished() or QDialog.accepted() On 11/12/13 09:17, Janwillem van Dijk wrote: > Hi, I have a PySide script that uses > QFileDialog.getExistingDirectory(). After clicking the Open button the > script proceeds with a lengthy part that processes a files list and > writes to a QPlainTextEdit. Unfortunately the QFileDialog widget does > only disappear after this processing is finished, hiding the > QPlainTextEdit. > > How can I make that the QFileDialog widget is gone before the > processing starts? > > Cheers, Janwillem > > > > > > _______________________________________________ > PySide mailing list > PySide at qt-project.org > http://lists.qt-project.org/mailman/listinfo/pyside -------------- next part -------------- An HTML attachment was scrubbed... URL: From jwevandijk at xs4all.nl Tue Dec 10 21:56:54 2013 From: jwevandijk at xs4all.nl (Janwillem van Dijk) Date: Tue, 10 Dec 2013 21:56:54 +0100 Subject: [PySide] wait for QFileDialog to close In-Reply-To: References: <52A776CA.60704@xs4all.nl> Message-ID: <52A78016.4020008@xs4all.nl> Here is the snippet: It reads the filenames in a folder and determines new names for photo's based on the exif info. I apreciate that threading might be a solution but the problem seems too simple for that. Can you give an example on how to use the signal concept? self.outFolder = QFileDialog.getExistingDirectory( caption='Destination folder', dir=self.defOutFolder) self.outFiles = [] if self.outFolder: self.outFolder = self.outFolder.replace('\\', '/') self.lineEdit_dest.setText(self.outFolder) self.progressBar.setRange(0, self.numFiles) for i, fname in enumerate(self.inFiles): self.progressBar.setValue(i + 1) newpath, newfname = rename_photo(self.inFolder, fname) newpath = path.join(self.outFolder, newpath) self.outFiles.append([fname, newpath, newfname]) s = fname + ' --> ' + self.outFolder + '\n' s += path.join(newpath, newfname).replace(self.outFolder, '') self.plainTextEdit_dest.appendPlainText(s) On 10/12/13 21:35, Sean Fisk wrote: > > Hi Janwillem, > > Are you running the “lengthy part that processes a files list” within > the GUI thread? If so, you will probably see your GUI hang while this > is happening (you won’t be able to click or do anything). In this > case, you should consider running the processing in a different thread > using QThread > > or QThreadPool > . > > Can you post the relevant part of the code? > > Thanks, > > > > -- > Sean Fisk > > > On Tue, Dec 10, 2013 at 3:17 PM, Janwillem van Dijk > > wrote: > > Hi, I have a PySide script that uses > QFileDialog.getExistingDirectory(). After clicking the Open button > the script proceeds with a lengthy part that processes a files > list and writes to a QPlainTextEdit. Unfortunately the QFileDialog > widget does only disappear after this processing is finished, > hiding the QPlainTextEdit. > > How can I make that the QFileDialog widget is gone before the > processing starts? > > Cheers, Janwillem > > > > > _______________________________________________ > PySide mailing list > PySide at qt-project.org > http://lists.qt-project.org/mailman/listinfo/pyside > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From frank at ohufx.com Tue Dec 10 22:43:09 2013 From: frank at ohufx.com (Frank Rueter | OHUfx) Date: Wed, 11 Dec 2013 10:43:09 +1300 Subject: [PySide] wait for QFileDialog to close In-Reply-To: <52A78016.4020008@xs4all.nl> References: <52A776CA.60704@xs4all.nl> <52A78016.4020008@xs4all.nl> Message-ID: <52A78AED.3070505@ohufx.com> Here is an example using signals/slots On 11/12/13 09:56, Janwillem van Dijk wrote: > > Here is the snippet: It reads the filenames in a folder and determines > new names for photo's based on the exif info. > > I apreciate that threading might be a solution but the problem seems > too simple for that. Can you give an example on how to use the signal > concept? > > > self.outFolder = QFileDialog.getExistingDirectory( > > caption='Destination folder', dir=self.defOutFolder) > > self.outFiles = [] > > if self.outFolder: > > self.outFolder = self.outFolder.replace('\\', '/') > > self.lineEdit_dest.setText(self.outFolder) > > self.progressBar.setRange(0, self.numFiles) > > for i, fname in enumerate(self.inFiles): > > self.progressBar.setValue(i + 1) > > newpath, newfname = rename_photo(self.inFolder, fname) > > newpath = path.join(self.outFolder, newpath) > > self.outFiles.append([fname, newpath, newfname]) > > s = fname + ' --> ' + self.outFolder + '\n' > > s += path.join(newpath, newfname).replace(self.outFolder, '') > > self.plainTextEdit_dest.appendPlainText(s) > > > > On 10/12/13 21:35, Sean Fisk wrote: >> >> Hi Janwillem, >> >> Are you running the “lengthy part that processes a files list” within >> the GUI thread? If so, you will probably see your GUI hang while this >> is happening (you won’t be able to click or do anything). In this >> case, you should consider running the processing in a different >> thread using QThread >> >> or QThreadPool >> . >> >> Can you post the relevant part of the code? >> >> Thanks, >> >> >> >> -- >> Sean Fisk >> >> >> On Tue, Dec 10, 2013 at 3:17 PM, Janwillem van Dijk >> > wrote: >> >> Hi, I have a PySide script that uses >> QFileDialog.getExistingDirectory(). After clicking the Open >> button the script proceeds with a lengthy part that processes a >> files list and writes to a QPlainTextEdit. Unfortunately the >> QFileDialog widget does only disappear after this processing is >> finished, hiding the QPlainTextEdit. >> >> How can I make that the QFileDialog widget is gone before the >> processing starts? >> >> Cheers, Janwillem >> >> >> >> >> _______________________________________________ >> PySide mailing list >> PySide at qt-project.org >> http://lists.qt-project.org/mailman/listinfo/pyside >> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: QFileBrowserSignal.py Type: text/x-python Size: 1236 bytes Desc: not available URL: From frank at ohufx.com Wed Dec 11 01:03:50 2013 From: frank at ohufx.com (Frank Rueter | OHUfx) Date: Wed, 11 Dec 2013 13:03:50 +1300 Subject: [PySide] secure password handling In-Reply-To: <4FDE5351.10502@ohufx.com> References: <4FDA78C7.6030703@ohufx.com> <1339746756.12308.2.camel@farnsworth> <4FDE5351.10502@ohufx.com> Message-ID: <52A7ABE6.4080106@ohufx.com> just picking up on this again: I'm still wondering what the best approach is in a PySide app to get from the plain text password that a user enters in a widget to an encrypted version of it while minimising the risk of theft of the original password?! I am currently encrypting the password via rsa using a public key and decrypting it on the server side with a private key. That's all nice, but what about the text that is entered in the widget itself? Isn't it too easy to hack the code to grab the password before it is encrypted? Even if I distribute the respective pyside and password code as pyc? Is it a feasible idea to have a pre-compiled PySide widget (not sure how to do that) that encrypts the password upon reception and only ever store the result of that? I guess this is a scenario where it would be of benefit to use C++ or other compiled languaes (which is beyond my knowledge). I would greatly appreciate people's input on this! Cheers, frank On 18/06/12 09:59, Frank Rueter | OHUfx wrote: > Thanks Srini. > > On 18/06/12 5:44 AM, Srini Kommoori wrote: >> For a desktop application, I would recommend using keyring >> http://pypi.python.org/pypi/keyring >> >> For file level password application, I would use PBKDF2 with very high >> iteration count. For my application, Safebox, I have used this method. >> Here are the details. >> http://safebox.fabulasolutions.com/p/safebox-crypto-architecture.html >> >> all the best >> >> On Jun 15, 2012, at 12:52 AM, Henry Gomersall wrote: >> >>> On Fri, 2012-06-15 at 11:50 +1200, Frank Rueter | OHUfx wrote: >>>> I'm wondering about the best way to handle password input in PySide. >>>> I know about python's hashlib, but am wondering if there is a better >>>> way >>>> to provide security between the user's input into a PySide widget and >>>> the hashing. A friend was wondering about a precompiled widget that >>>> does >>>> the hashing directly so the password is never once stored anywhere as >>>> plain text. >>>> >>>> What are people's approaches for this? >>> so, in light of the recent LinkedIn debacle, the following was brought >>> to my attention: >>> >>> http://codahale.com/how-to-safely-store-a-password/ >>> >>> I'm not a security expert, which is why I feel the need to listen to all >>> the arguments! >>> >>> Cheers, >>> >>> Henry >>> >>> _______________________________________________ >>> PySide mailing list >>> PySide at qt-project.org >>> http://lists.qt-project.org/mailman/listinfo/pyside > _______________________________________________ > PySide mailing list > PySide at qt-project.org > http://lists.qt-project.org/mailman/listinfo/pyside From sean at seanfisk.com Wed Dec 11 05:45:55 2013 From: sean at seanfisk.com (Sean Fisk) Date: Tue, 10 Dec 2013 23:45:55 -0500 Subject: [PySide] wait for QFileDialog to close In-Reply-To: <52A78AED.3070505@ohufx.com> References: <52A776CA.60704@xs4all.nl> <52A78016.4020008@xs4all.nl> <52A78AED.3070505@ohufx.com> Message-ID: Frank, Your example is a good demonstration of QFileDialog‘s signals. However, since the processing runs in the GUI thread, the progress bar is virtually useless as the GUI has no time to update it. It starts empty, the application hangs, and then it is filled when the processing is done. Janwillem, As I see it, if you would like a progress bar, you have three options: 1. Call QCoreApplication.processEvents()during your processing code. This is not always a great idea, and more of a hack than a solution. But it usually works. 2. Split your processing into chunks as in this example. However, the code is a bit convoluted and it still runs in the GUI thread. The whole page that contains that example is a great read for asynchronous programming. 3. Send your processing to a thread, and dispatch events from the thread indicating the progress. The first two solutions involve running processing code within the GUI thread. If any step of the processing takes longer than a second, then it’s probably not a good idea as the user will see the application hang. Here is an example implementation of the third solution: #!/usr/bin/env python # Example: Asynchronously process a directory of files with a progress bar. import sysimport osimport time from PySide import QtCore, QtGui class ProcessingThread(QtCore.QThread): # Fired when each file is processed. file_processed = QtCore.Signal(int, str) def __init__(self, parent=None): super(ProcessingThread, self).__init__(parent) self.files = [] def run(self): # Code that's run in the thread. for i, filename in enumerate(self.files): # The actual code for one file goes here. Stubbed out with # time.sleep() for now. time.sleep(0.5) print 'Processed:', filename # Send update to the GUI thread. self.file_processed.emit(i + 1, filename) class MyWidget(QtGui.QWidget): def __init__(self, parent=None): super(MyWidget, self).__init__(parent) # Setup UI. self._layout = QtGui.QVBoxLayout(self) self._button = QtGui.QPushButton('Open files...') self._progress = QtGui.QProgressBar() self._filelist = QtGui.QPlainTextEdit() self._layout.addWidget(self._button) self._layout.addWidget(self._filelist) self._layout.addWidget(self._progress) # Setup events. self._button.clicked.connect(self._button_clicked) # Create the thread. Note that this doesn't actually _start_ it. self._thread = ProcessingThread() self._thread.file_processed.connect(self._file_processed) # We need to wait for the thread before exiting. Either use this or # don't let the user close the window if processing is happening. See # the next method in this class. QtCore.QCoreApplication.instance().aboutToQuit.connect( self._thread.wait) # def closeEvent(self, event): # # This is an alternative to waiting for the threads. Just don't let # # the user close the window. # if self._thread.isRunning(): # QtGui.QMessageBox.critical( # self, 'Processing', # 'Cannot exit while processing is happening.') # event.ignore() # else: # event.accept() def _button_clicked(self): # If we are already running the processing, produce an error. if self._thread.isRunning(): QtGui.QMessageBox.critical( self, 'Processing', 'Can only process one directory at a time.') return # Get the directory name from the user. dir_name = QtGui.QFileDialog.getExistingDirectory( parent=self, caption='Choose files...', dir=os.getcwd()) # Activate the main dialog as it will be deactivated for some reason # after the file dialog closes (at least on my machine). self.activateWindow() # Get the list of files in the directory and prime the progress bar. files = os.listdir(dir_name) # Set values for progress bar. self._progress.setRange(0, len(files)) self._progress.setValue(0) # Create and start the thread. self._thread.files = files self._thread.start() def _file_processed(self, num_files_processed, filename): # Called for each file that is processed. self._filelist.appendPlainText(filename) self._progress.setValue(num_files_processed) if __name__ == '__main__': app = QtGui.QApplication(sys.argv) w = MyWidget() w.show() w.raise_() raise SystemExit(app.exec_()) This is all fine, but it might not solve your original problem of the file dialog not closing. On my Mac, the file dialog is gone as soon as the call to getExistingDirectory() finishes. However, since I don’t have a runnable portion of your code, I can’t really test it. I would recommend attempting to run my example to see if it exhibits the same problem as your program. Hope this helps! Cheers, -- Sean Fisk On Tue, Dec 10, 2013 at 4:43 PM, Frank Rueter | OHUfx wrote: > Here is an example using signals/slots > > > On 11/12/13 09:56, Janwillem van Dijk wrote: > > Here is the snippet: It reads the filenames in a folder and determines > new names for photo's based on the exif info. > > I apreciate that threading might be a solution but the problem seems too > simple for that. Can you give an example on how to use the signal concept? > > > self.outFolder = QFileDialog.getExistingDirectory( > > caption='Destination folder', dir=self.defOutFolder) > > self.outFiles = [] > > if self.outFolder: > > self.outFolder = self.outFolder.replace('\\', '/') > > self.lineEdit_dest.setText(self.outFolder) > > self.progressBar.setRange(0, self.numFiles) > > for i, fname in enumerate(self.inFiles): > > self.progressBar.setValue(i + 1) > > newpath, newfname = rename_photo(self.inFolder, fname) > > newpath = path.join(self.outFolder, newpath) > > self.outFiles.append([fname, newpath, newfname]) > > s = fname + ' --> ' + self.outFolder + '\n' > > s += path.join(newpath, newfname).replace(self.outFolder, '') > > self.plainTextEdit_dest.appendPlainText(s) > > > > On 10/12/13 21:35, Sean Fisk wrote: > > Hi Janwillem, > > Are you running the “lengthy part that processes a files list” within the > GUI thread? If so, you will probably see your GUI hang while this is > happening (you won’t be able to click or do anything). In this case, you > should consider running the processing in a different thread using QThreador > QThreadPool > . > > Can you post the relevant part of the code? > > Thanks, > > > -- > Sean Fisk > > > On Tue, Dec 10, 2013 at 3:17 PM, Janwillem van Dijk wrote: > >> Hi, I have a PySide script that uses QFileDialog.getExistingDirectory(). >> After clicking the Open button the script proceeds with a lengthy part that >> processes a files list and writes to a QPlainTextEdit. Unfortunately the >> QFileDialog widget does only disappear after this processing is finished, >> hiding the QPlainTextEdit. >> >> How can I make that the QFileDialog widget is gone before the processing >> starts? >> >> Cheers, Janwillem >> >> >> >> >> _______________________________________________ >> PySide mailing list >> PySide at qt-project.org >> http://lists.qt-project.org/mailman/listinfo/pyside >> >> > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From frank at ohufx.com Wed Dec 11 05:49:11 2013 From: frank at ohufx.com (Frank Rueter | OHUfx) Date: Wed, 11 Dec 2013 17:49:11 +1300 Subject: [PySide] wait for QFileDialog to close In-Reply-To: References: <52A776CA.60704@xs4all.nl> <52A78016.4020008@xs4all.nl> <52A78AED.3070505@ohufx.com> Message-ID: <52A7EEC7.5000704@ohufx.com> Hi Sean, actually the progress bar works just fine for me in my example. How come? On 11/12/13 17:45, Sean Fisk wrote: > > Frank, > > Your example is a good demonstration of |QFileDialog|‘s signals. > However, since the processing runs in the GUI thread, the progress bar > is virtually useless as the GUI has no time to update it. It starts > empty, the application hangs, and then it is filled when the > processing is done. > > Janwillem, > > As I see it, if you would like a progress bar, you have three options: > > 1. Call |QCoreApplication.processEvents()| > > during your processing code. This is not always a great idea, and > more of a hack than a solution. But it usually works. > 2. Split your processing into chunks as in this example > . > However, the code is a bit convoluted and it still runs in the GUI > thread. The whole page that contains that example is a great read > for asynchronous programming. > 3. Send your processing to a thread, and dispatch events from the > thread indicating the progress. > > The first two solutions involve running processing code within the GUI > thread. If any step of the processing takes longer than a second, then > it’s probably not a good idea as the user will see the application > hang. Here is an example implementation of the third solution: > > |#!/usr/bin/env python > > # Example: Asynchronously process a directory of files with a progress bar. > > import sys > import os > import time > > from PySideimport QtCore, QtGui > > class ProcessingThread(QtCore.QThread): > # Fired when each file is processed. > file_processed = QtCore.Signal(int, str) > > def __init__(self, parent=None): > super(ProcessingThread, self).__init__(parent) > self.files = [] > > def run(self): > # Code that's run in the thread. > for i, filenamein enumerate(self.files): > # The actual code for one file goes here. Stubbed out with > # time.sleep() for now. > time.sleep(0.5) > print 'Processed:', filename > # Send update to the GUI thread. > self.file_processed.emit(i +1, filename) > > class MyWidget(QtGui.QWidget): > def __init__(self, parent=None): > super(MyWidget, self).__init__(parent) > > # Setup UI. > self._layout = QtGui.QVBoxLayout(self) > self._button = QtGui.QPushButton('Open files...') > self._progress = QtGui.QProgressBar() > self._filelist = QtGui.QPlainTextEdit() > self._layout.addWidget(self._button) > self._layout.addWidget(self._filelist) > self._layout.addWidget(self._progress) > > # Setup events. > self._button.clicked.connect(self._button_clicked) > > # Create the thread. Note that this doesn't actually _start_ it. > self._thread = ProcessingThread() > self._thread.file_processed.connect(self._file_processed) > > # We need to wait for the thread before exiting. Either use this or > # don't let the user close the window if processing is happening. See > # the next method in this class. > QtCore.QCoreApplication.instance().aboutToQuit.connect( > self._thread.wait) > > # def closeEvent(self, event): > # # This is an alternative to waiting for the threads. Just don't let > # # the user close the window. > # if self._thread.isRunning(): > # QtGui.QMessageBox.critical( > # self, 'Processing', > # 'Cannot exit while processing is happening.') > # event.ignore() > # else: > # event.accept() > > def _button_clicked(self): > # If we are already running the processing, produce an error. > if self._thread.isRunning(): > QtGui.QMessageBox.critical( > self,'Processing', > 'Can only process one directory at a time.') > return > > # Get the directory name from the user. > dir_name = QtGui.QFileDialog.getExistingDirectory( > parent=self, > caption='Choose files...', > dir=os.getcwd()) > > # Activate the main dialog as it will be deactivated for some reason > # after the file dialog closes (at least on my machine). > self.activateWindow() > > # Get the list of files in the directory and prime the progress bar. > files = os.listdir(dir_name) > > # Set values for progress bar. > self._progress.setRange(0, len(files)) > self._progress.setValue(0) > > # Create and start the thread. > self._thread.files = files > self._thread.start() > > def _file_processed(self, num_files_processed, filename): > # Called for each file that is processed. > self._filelist.appendPlainText(filename) > self._progress.setValue(num_files_processed) > > if __name__ =='__main__': > app = QtGui.QApplication(sys.argv) > w = MyWidget() > w.show() > w.raise_() > raise SystemExit(app.exec_())| > > This is all fine, but it might not solve your original problem of the > file dialog not closing. On my Mac, the file dialog is gone as soon as > the call to |getExistingDirectory()| finishes. However, since I don’t > have a runnable portion of your code, I can’t really test it. I would > recommend attempting to run my example to see if it exhibits the same > problem as your program. Hope this helps! > > Cheers, > > > > > -- > Sean Fisk > > > On Tue, Dec 10, 2013 at 4:43 PM, Frank Rueter | OHUfx > wrote: > > Here is an example using signals/slots > > > On 11/12/13 09:56, Janwillem van Dijk wrote: >> >> Here is the snippet: It reads the filenames in a folder and >> determines new names for photo's based on the exif info. >> >> I apreciate that threading might be a solution but the problem >> seems too simple for that. Can you give an example on how to use >> the signal concept? >> >> >> self.outFolder = QFileDialog.getExistingDirectory( >> >> caption='Destination folder', dir=self.defOutFolder) >> >> self.outFiles = [] >> >> if self.outFolder: >> >> self.outFolder = self.outFolder.replace('\\', '/') >> >> self.lineEdit_dest.setText(self.outFolder) >> >> self.progressBar.setRange(0, self.numFiles) >> >> for i, fname in enumerate(self.inFiles): >> >> self.progressBar.setValue(i + 1) >> >> newpath, newfname = rename_photo(self.inFolder, fname) >> >> newpath = path.join(self.outFolder, newpath) >> >> self.outFiles.append([fname, newpath, newfname]) >> >> s = fname + ' --> ' + self.outFolder + '\n' >> >> s += path.join(newpath, newfname).replace(self.outFolder, '') >> >> self.plainTextEdit_dest.appendPlainText(s) >> >> >> >> On 10/12/13 21:35, Sean Fisk wrote: >>> >>> Hi Janwillem, >>> >>> Are you running the “lengthy part that processes a files list” >>> within the GUI thread? If so, you will probably see your GUI >>> hang while this is happening (you won’t be able to click or do >>> anything). In this case, you should consider running the >>> processing in a different thread using QThread >>> >>> or QThreadPool >>> . >>> >>> Can you post the relevant part of the code? >>> >>> Thanks, >>> >>> >>> >>> -- >>> Sean Fisk >>> >>> >>> On Tue, Dec 10, 2013 at 3:17 PM, Janwillem van Dijk >>> > wrote: >>> >>> Hi, I have a PySide script that uses >>> QFileDialog.getExistingDirectory(). After clicking the Open >>> button the script proceeds with a lengthy part that >>> processes a files list and writes to a QPlainTextEdit. >>> Unfortunately the QFileDialog widget does only disappear >>> after this processing is finished, hiding the QPlainTextEdit. >>> >>> How can I make that the QFileDialog widget is gone before >>> the processing starts? >>> >>> Cheers, Janwillem >>> >>> >>> >>> >>> _______________________________________________ >>> PySide mailing list >>> PySide at qt-project.org >>> http://lists.qt-project.org/mailman/listinfo/pyside >>> >>> >> > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jwevandijk at xs4all.nl Wed Dec 11 15:16:27 2013 From: jwevandijk at xs4all.nl (Janwillem van Dijk) Date: Wed, 11 Dec 2013 15:16:27 +0100 Subject: [PySide] wait for QFileDialog to close In-Reply-To: References: <52A776CA.60704@xs4all.nl> <52A78016.4020008@xs4all.nl> <52A78AED.3070505@ohufx.com> Message-ID: <52A873BB.6040507@xs4all.nl> The solution Frank proposed yesterday works (after I found out that you can get the output using selectedFiles()[0]). No problems with the progressbar. The actual processing can take a bit long because the exif's of digital camera shots are analysed (GExiv2 for photos and exiftool for movies ) and than copied to folders as /camara_make/year/month/imagetype/yyyymmddhhmmss_fname. When copying more than say 50 16MB raw photos the gui becomes blocked. In other apps I indeed solved that with threading but, although not elegant, I decided to live with that for this one. Many thanks for teaching me this extra bit of Python. Cheers, Janwillem On 11/12/13 05:45, Sean Fisk wrote: > > Frank, > > Your example is a good demonstration of |QFileDialog|‘s signals. > However, since the processing runs in the GUI thread, the progress bar > is virtually useless as the GUI has no time to update it. It starts > empty, the application hangs, and then it is filled when the > processing is done. > > Janwillem, > > As I see it, if you would like a progress bar, you have three options: > > 1. Call |QCoreApplication.processEvents()| > > during your processing code. This is not always a great idea, and > more of a hack than a solution. But it usually works. > 2. Split your processing into chunks as in this example > . > However, the code is a bit convoluted and it still runs in the GUI > thread. The whole page that contains that example is a great read > for asynchronous programming. > 3. Send your processing to a thread, and dispatch events from the > thread indicating the progress. > > The first two solutions involve running processing code within the GUI > thread. If any step of the processing takes longer than a second, then > it’s probably not a good idea as the user will see the application > hang. Here is an example implementation of the third solution: > > |#!/usr/bin/env python > > # Example: Asynchronously process a directory of files with a progress bar. > > import sys > import os > import time > > from PySideimport QtCore, QtGui > > class ProcessingThread(QtCore.QThread): > # Fired when each file is processed. > file_processed = QtCore.Signal(int, str) > > def __init__(self, parent=None): > super(ProcessingThread, self).__init__(parent) > self.files = [] > > def run(self): > # Code that's run in the thread. > for i, filenamein enumerate(self.files): > # The actual code for one file goes here. Stubbed out with > # time.sleep() for now. > time.sleep(0.5) > print 'Processed:', filename > # Send update to the GUI thread. > self.file_processed.emit(i +1, filename) > > class MyWidget(QtGui.QWidget): > def __init__(self, parent=None): > super(MyWidget, self).__init__(parent) > > # Setup UI. > self._layout = QtGui.QVBoxLayout(self) > self._button = QtGui.QPushButton('Open files...') > self._progress = QtGui.QProgressBar() > self._filelist = QtGui.QPlainTextEdit() > self._layout.addWidget(self._button) > self._layout.addWidget(self._filelist) > self._layout.addWidget(self._progress) > > # Setup events. > self._button.clicked.connect(self._button_clicked) > > # Create the thread. Note that this doesn't actually _start_ it. > self._thread = ProcessingThread() > self._thread.file_processed.connect(self._file_processed) > > # We need to wait for the thread before exiting. Either use this or > # don't let the user close the window if processing is happening. See > # the next method in this class. > QtCore.QCoreApplication.instance().aboutToQuit.connect( > self._thread.wait) > > # def closeEvent(self, event): > # # This is an alternative to waiting for the threads. Just don't let > # # the user close the window. > # if self._thread.isRunning(): > # QtGui.QMessageBox.critical( > # self, 'Processing', > # 'Cannot exit while processing is happening.') > # event.ignore() > # else: > # event.accept() > > def _button_clicked(self): > # If we are already running the processing, produce an error. > if self._thread.isRunning(): > QtGui.QMessageBox.critical( > self,'Processing', > 'Can only process one directory at a time.') > return > > # Get the directory name from the user. > dir_name = QtGui.QFileDialog.getExistingDirectory( > parent=self, > caption='Choose files...', > dir=os.getcwd()) > > # Activate the main dialog as it will be deactivated for some reason > # after the file dialog closes (at least on my machine). > self.activateWindow() > > # Get the list of files in the directory and prime the progress bar. > files = os.listdir(dir_name) > > # Set values for progress bar. > self._progress.setRange(0, len(files)) > self._progress.setValue(0) > > # Create and start the thread. > self._thread.files = files > self._thread.start() > > def _file_processed(self, num_files_processed, filename): > # Called for each file that is processed. > self._filelist.appendPlainText(filename) > self._progress.setValue(num_files_processed) > > if __name__ =='__main__': > app = QtGui.QApplication(sys.argv) > w = MyWidget() > w.show() > w.raise_() > raise SystemExit(app.exec_())| > > This is all fine, but it might not solve your original problem of the > file dialog not closing. On my Mac, the file dialog is gone as soon as > the call to |getExistingDirectory()| finishes. However, since I don’t > have a runnable portion of your code, I can’t really test it. I would > recommend attempting to run my example to see if it exhibits the same > problem as your program. Hope this helps! > > Cheers, > > > > > -- > Sean Fisk > > > On Tue, Dec 10, 2013 at 4:43 PM, Frank Rueter | OHUfx > wrote: > > Here is an example using signals/slots > > > On 11/12/13 09:56, Janwillem van Dijk wrote: >> >> Here is the snippet: It reads the filenames in a folder and >> determines new names for photo's based on the exif info. >> >> I apreciate that threading might be a solution but the problem >> seems too simple for that. Can you give an example on how to use >> the signal concept? >> >> >> self.outFolder = QFileDialog.getExistingDirectory( >> >> caption='Destination folder', dir=self.defOutFolder) >> >> self.outFiles = [] >> >> if self.outFolder: >> >> self.outFolder = self.outFolder.replace('\\', '/') >> >> self.lineEdit_dest.setText(self.outFolder) >> >> self.progressBar.setRange(0, self.numFiles) >> >> for i, fname in enumerate(self.inFiles): >> >> self.progressBar.setValue(i + 1) >> >> newpath, newfname = rename_photo(self.inFolder, fname) >> >> newpath = path.join(self.outFolder, newpath) >> >> self.outFiles.append([fname, newpath, newfname]) >> >> s = fname + ' --> ' + self.outFolder + '\n' >> >> s += path.join(newpath, newfname).replace(self.outFolder, '') >> >> self.plainTextEdit_dest.appendPlainText(s) >> >> >> >> On 10/12/13 21:35, Sean Fisk wrote: >>> >>> Hi Janwillem, >>> >>> Are you running the “lengthy part that processes a files list” >>> within the GUI thread? If so, you will probably see your GUI >>> hang while this is happening (you won’t be able to click or do >>> anything). In this case, you should consider running the >>> processing in a different thread using QThread >>> >>> or QThreadPool >>> . >>> >>> Can you post the relevant part of the code? >>> >>> Thanks, >>> >>> >>> >>> -- >>> Sean Fisk >>> >>> >>> On Tue, Dec 10, 2013 at 3:17 PM, Janwillem van Dijk >>> > wrote: >>> >>> Hi, I have a PySide script that uses >>> QFileDialog.getExistingDirectory(). After clicking the Open >>> button the script proceeds with a lengthy part that >>> processes a files list and writes to a QPlainTextEdit. >>> Unfortunately the QFileDialog widget does only disappear >>> after this processing is finished, hiding the QPlainTextEdit. >>> >>> How can I make that the QFileDialog widget is gone before >>> the processing starts? >>> >>> Cheers, Janwillem >>> >>> >>> >>> >>> _______________________________________________ >>> PySide mailing list >>> PySide at qt-project.org >>> http://lists.qt-project.org/mailman/listinfo/pyside >>> >>> >> > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From sean at seanfisk.com Wed Dec 11 21:56:13 2013 From: sean at seanfisk.com (Sean Fisk) Date: Wed, 11 Dec 2013 15:56:13 -0500 Subject: [PySide] wait for QFileDialog to close In-Reply-To: <52A873BB.6040507@xs4all.nl> References: <52A776CA.60704@xs4all.nl> <52A78016.4020008@xs4all.nl> <52A78AED.3070505@ohufx.com> <52A873BB.6040507@xs4all.nl> Message-ID: Janwillem, I'm glad you were able to able to figure out the problem. Sorry for my red herrings! Frank, I thought about it, and I have no idea why the progress bar works fine for you and not for me. It hangs for me, which is exactly what I expected to happen. Maybe some platform difference? I'm on Mac OS 10.6 with PySide 1.2.1. -- Sean Fisk On Wed, Dec 11, 2013 at 9:16 AM, Janwillem van Dijk wrote: > The solution Frank proposed yesterday works (after I found out that you > can get the output using selectedFiles()[0]). > No problems with the progressbar. > The actual processing can take a bit long because the exif's of digital > camera shots are analysed (GExiv2 for photos and exiftool for movies ) and > than copied to folders as > /camara_make/year/month/imagetype/yyyymmddhhmmss_fname. When copying more > than say 50 16MB raw photos the gui becomes blocked. In other apps I indeed > solved that with threading but, although not elegant, I decided to live > with that for this one. > Many thanks for teaching me this extra bit of Python. > Cheers, Janwillem > > > On 11/12/13 05:45, Sean Fisk wrote: > > Frank, > > Your example is a good demonstration of QFileDialog‘s signals. However, > since the processing runs in the GUI thread, the progress bar is virtually > useless as the GUI has no time to update it. It starts empty, the > application hangs, and then it is filled when the processing is done. > > Janwillem, > > As I see it, if you would like a progress bar, you have three options: > > 1. Call QCoreApplication.processEvents()during your processing code. This is not always a great idea, and more of a > hack than a solution. But it usually works. > 2. Split your processing into chunks as in this example. > However, the code is a bit convoluted and it still runs in the GUI thread. > The whole page that contains that example is a great read for asynchronous > programming. > 3. Send your processing to a thread, and dispatch events from the > thread indicating the progress. > > The first two solutions involve running processing code within the GUI > thread. If any step of the processing takes longer than a second, then it’s > probably not a good idea as the user will see the application hang. Here is > an example implementation of the third solution: > > #!/usr/bin/env python > # Example: Asynchronously process a directory of files with a progress bar. > import sysimport osimport time > from PySide import QtCore, QtGui > class ProcessingThread(QtCore.QThread): > # Fired when each file is processed. > file_processed = QtCore.Signal(int, str) > > def __init__(self, parent=None): > super(ProcessingThread, self).__init__(parent) > self.files = [] > > def run(self): > # Code that's run in the thread. > for i, filename in enumerate(self.files): > # The actual code for one file goes here. Stubbed out with > # time.sleep() for now. > time.sleep(0.5) > print 'Processed:', filename > # Send update to the GUI thread. > self.file_processed.emit(i + 1, filename) > class MyWidget(QtGui.QWidget): > def __init__(self, parent=None): > super(MyWidget, self).__init__(parent) > > # Setup UI. > self._layout = QtGui.QVBoxLayout(self) > self._button = QtGui.QPushButton('Open files...') > self._progress = QtGui.QProgressBar() > self._filelist = QtGui.QPlainTextEdit() > self._layout.addWidget(self._button) > self._layout.addWidget(self._filelist) > self._layout.addWidget(self._progress) > > # Setup events. > self._button.clicked.connect(self._button_clicked) > > # Create the thread. Note that this doesn't actually _start_ it. > self._thread = ProcessingThread() > self._thread.file_processed.connect(self._file_processed) > > # We need to wait for the thread before exiting. Either use this or > # don't let the user close the window if processing is happening. See > # the next method in this class. > QtCore.QCoreApplication.instance().aboutToQuit.connect( > self._thread.wait) > > # def closeEvent(self, event): > # # This is an alternative to waiting for the threads. Just don't let > # # the user close the window. > # if self._thread.isRunning(): > # QtGui.QMessageBox.critical( > # self, 'Processing', > # 'Cannot exit while processing is happening.') > # event.ignore() > # else: > # event.accept() > > def _button_clicked(self): > # If we are already running the processing, produce an error. > if self._thread.isRunning(): > QtGui.QMessageBox.critical( > self, 'Processing', > 'Can only process one directory at a time.') > return > > # Get the directory name from the user. > dir_name = QtGui.QFileDialog.getExistingDirectory( > parent=self, > caption='Choose files...', > dir=os.getcwd()) > > # Activate the main dialog as it will be deactivated for some reason > # after the file dialog closes (at least on my machine). > self.activateWindow() > > # Get the list of files in the directory and prime the progress bar. > files = os.listdir(dir_name) > > # Set values for progress bar. > self._progress.setRange(0, len(files)) > self._progress.setValue(0) > > # Create and start the thread. > self._thread.files = files > self._thread.start() > > def _file_processed(self, num_files_processed, filename): > # Called for each file that is processed. > self._filelist.appendPlainText(filename) > self._progress.setValue(num_files_processed) > if __name__ == '__main__': > app = QtGui.QApplication(sys.argv) > w = MyWidget() > w.show() > w.raise_() > raise SystemExit(app.exec_()) > > This is all fine, but it might not solve your original problem of the file > dialog not closing. On my Mac, the file dialog is gone as soon as the call > to getExistingDirectory() finishes. However, since I don’t have a > runnable portion of your code, I can’t really test it. I would recommend > attempting to run my example to see if it exhibits the same problem as your > program. Hope this helps! > > Cheers, > > > > -- > Sean Fisk > > > On Tue, Dec 10, 2013 at 4:43 PM, Frank Rueter | OHUfx wrote: > >> Here is an example using signals/slots >> >> >> On 11/12/13 09:56, Janwillem van Dijk wrote: >> >> Here is the snippet: It reads the filenames in a folder and determines >> new names for photo's based on the exif info. >> >> I apreciate that threading might be a solution but the problem seems too >> simple for that. Can you give an example on how to use the signal concept? >> >> >> self.outFolder = QFileDialog.getExistingDirectory( >> >> caption='Destination folder', dir=self.defOutFolder) >> >> self.outFiles = [] >> >> if self.outFolder: >> >> self.outFolder = self.outFolder.replace('\\', '/') >> >> self.lineEdit_dest.setText(self.outFolder) >> >> self.progressBar.setRange(0, self.numFiles) >> >> for i, fname in enumerate(self.inFiles): >> >> self.progressBar.setValue(i + 1) >> >> newpath, newfname = rename_photo(self.inFolder, fname) >> >> newpath = path.join(self.outFolder, newpath) >> >> self.outFiles.append([fname, newpath, newfname]) >> >> s = fname + ' --> ' + self.outFolder + '\n' >> >> s += path.join(newpath, newfname).replace(self.outFolder, '') >> >> self.plainTextEdit_dest.appendPlainText(s) >> >> >> >> On 10/12/13 21:35, Sean Fisk wrote: >> >> Hi Janwillem, >> >> Are you running the “lengthy part that processes a files list” within the >> GUI thread? If so, you will probably see your GUI hang while this is >> happening (you won’t be able to click or do anything). In this case, you >> should consider running the processing in a different thread using >> QThreador >> QThreadPool >> . >> >> Can you post the relevant part of the code? >> >> Thanks, >> >> >> -- >> Sean Fisk >> >> >> On Tue, Dec 10, 2013 at 3:17 PM, Janwillem van Dijk > > wrote: >> >>> Hi, I have a PySide script that uses >>> QFileDialog.getExistingDirectory(). After clicking the Open button the >>> script proceeds with a lengthy part that processes a files list and writes >>> to a QPlainTextEdit. Unfortunately the QFileDialog widget does only >>> disappear after this processing is finished, hiding the QPlainTextEdit. >>> >>> How can I make that the QFileDialog widget is gone before the processing >>> starts? >>> >>> Cheers, Janwillem >>> >>> >>> >>> >>> _______________________________________________ >>> PySide mailing list >>> PySide at qt-project.org >>> http://lists.qt-project.org/mailman/listinfo/pyside >>> >>> >> >> >> > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jwevandijk at xs4all.nl Wed Dec 11 22:30:36 2013 From: jwevandijk at xs4all.nl (Janwillem van Dijk) Date: Wed, 11 Dec 2013 22:30:36 +0100 Subject: [PySide] wait for QFileDialog to close In-Reply-To: References: <52A776CA.60704@xs4all.nl> <52A78016.4020008@xs4all.nl> <52A78AED.3070505@ohufx.com> <52A873BB.6040507@xs4all.nl> Message-ID: <52A8D97C.7040509@xs4all.nl> On 11/12/13 21:56, Sean Fisk wrote: > Janwillem, > > I'm glad you were able to able to figure out the problem. Sorry for my > red herrings! > > Frank, > > I thought about it, and I have no idea why the progress bar works fine > for you and not for me. It hangs for me, which is exactly what I > expected to happen. Maybe some platform difference? I'm on Mac OS 10.6 > with PySide 1.2.1. > > > -- > Sean Fisk > > > On Wed, Dec 11, 2013 at 9:16 AM, Janwillem van Dijk > > wrote: > > The solution Frank proposed yesterday works (after I found out > that you can get the output using selectedFiles()[0]). > No problems with the progressbar. > The actual processing can take a bit long because the exif's of > digital camera shots are analysed (GExiv2 for photos and exiftool > for movies ) and than copied to folders as > /camara_make/year/month/imagetype/yyyymmddhhmmss_fname. When > copying more than say 50 16MB raw photos the gui becomes blocked. > In other apps I indeed solved that with threading but, although > not elegant, I decided to live with that for this one. > Many thanks for teaching me this extra bit of Python. > Cheers, Janwillem > > > On 11/12/13 05:45, Sean Fisk wrote: >> >> Frank, >> >> Your example is a good demonstration of |QFileDialog|‘s signals. >> However, since the processing runs in the GUI thread, the >> progress bar is virtually useless as the GUI has no time to >> update it. It starts empty, the application hangs, and then it is >> filled when the processing is done. >> >> Janwillem, >> >> As I see it, if you would like a progress bar, you have three >> options: >> >> 1. Call |QCoreApplication.processEvents()| >> >> during your processing code. This is not always a great idea, >> and more of a hack than a solution. But it usually works. >> 2. Split your processing into chunks as in this example >> . >> However, the code is a bit convoluted and it still runs in >> the GUI thread. The whole page that contains that example is >> a great read for asynchronous programming. >> 3. Send your processing to a thread, and dispatch events from >> the thread indicating the progress. >> >> The first two solutions involve running processing code within >> the GUI thread. If any step of the processing takes longer than a >> second, then it’s probably not a good idea as the user will see >> the application hang. Here is an example implementation of the >> third solution: >> >> |#!/usr/bin/env python >> >> # Example: Asynchronously process a directory of files with a progress bar. >> >> import sys >> import os >> import time >> >> from PySideimport QtCore, QtGui >> >> class ProcessingThread(QtCore.QThread): >> # Fired when each file is processed. >> file_processed = QtCore.Signal(int, str) >> >> def __init__(self, parent=None): >> super(ProcessingThread, self).__init__(parent) >> self.files = [] >> >> def run(self): >> # Code that's run in the thread. >> for i, filenamein enumerate(self.files): >> # The actual code for one file goes here. Stubbed out with >> # time.sleep() for now. >> time.sleep(0.5) >> print 'Processed:', filename >> # Send update to the GUI thread. >> self.file_processed.emit(i +1, filename) >> >> class MyWidget(QtGui.QWidget): >> def __init__(self, parent=None): >> super(MyWidget, self).__init__(parent) >> >> # Setup UI. >> self._layout = QtGui.QVBoxLayout(self) >> self._button = QtGui.QPushButton('Open files...') >> self._progress = QtGui.QProgressBar() >> self._filelist = QtGui.QPlainTextEdit() >> self._layout.addWidget(self._button) >> self._layout.addWidget(self._filelist) >> self._layout.addWidget(self._progress) >> >> # Setup events. >> self._button.clicked.connect(self._button_clicked) >> >> # Create the thread. Note that this doesn't actually _start_ it. >> self._thread = ProcessingThread() >> self._thread.file_processed.connect(self._file_processed) >> >> # We need to wait for the thread before exiting. Either use this or >> # don't let the user close the window if processing is happening. See >> # the next method in this class. >> QtCore.QCoreApplication.instance().aboutToQuit.connect( >> self._thread.wait) >> >> # def closeEvent(self, event): >> # # This is an alternative to waiting for the threads. Just don't let >> # # the user close the window. >> # if self._thread.isRunning(): >> # QtGui.QMessageBox.critical( >> # self, 'Processing', >> # 'Cannot exit while processing is happening.') >> # event.ignore() >> # else: >> # event.accept() >> >> def _button_clicked(self): >> # If we are already running the processing, produce an error. >> if self._thread.isRunning(): >> QtGui.QMessageBox.critical( >> self,'Processing', >> 'Can only process one directory at a time.') >> return >> >> # Get the directory name from the user. >> dir_name = QtGui.QFileDialog.getExistingDirectory( >> parent=self, >> caption='Choose files...', >> dir=os.getcwd()) >> >> # Activate the main dialog as it will be deactivated for some reason >> # after the file dialog closes (at least on my machine). >> self.activateWindow() >> >> # Get the list of files in the directory and prime the progress bar. >> files = os.listdir(dir_name) >> >> # Set values for progress bar. >> self._progress.setRange(0, len(files)) >> self._progress.setValue(0) >> >> # Create and start the thread. >> self._thread.files = files >> self._thread.start() >> >> def _file_processed(self, num_files_processed, filename): >> # Called for each file that is processed. >> self._filelist.appendPlainText(filename) >> self._progress.setValue(num_files_processed) >> >> if __name__ =='__main__': >> app = QtGui.QApplication(sys.argv) >> w = MyWidget() >> w.show() >> w.raise_() >> raise SystemExit(app.exec_())| >> >> This is all fine, but it might not solve your original problem of >> the file dialog not closing. On my Mac, the file dialog is gone >> as soon as the call to |getExistingDirectory()| finishes. >> However, since I don’t have a runnable portion of your code, I >> can’t really test it. I would recommend attempting to run my >> example to see if it exhibits the same problem as your program. >> Hope this helps! >> >> Cheers, >> >> >> >> >> -- >> Sean Fisk >> >> >> On Tue, Dec 10, 2013 at 4:43 PM, Frank Rueter | OHUfx >> > wrote: >> >> Here is an example using signals/slots >> >> >> On 11/12/13 09:56, Janwillem van Dijk wrote: >>> >>> Here is the snippet: It reads the filenames in a folder and >>> determines new names for photo's based on the exif info. >>> >>> I apreciate that threading might be a solution but the >>> problem seems too simple for that. Can you give an example >>> on how to use the signal concept? >>> >>> >>> self.outFolder = QFileDialog.getExistingDirectory( >>> >>> caption='Destination folder', dir=self.defOutFolder) >>> >>> self.outFiles = [] >>> >>> if self.outFolder: >>> >>> self.outFolder = self.outFolder.replace('\\', '/') >>> >>> self.lineEdit_dest.setText(self.outFolder) >>> >>> self.progressBar.setRange(0, self.numFiles) >>> >>> for i, fname in enumerate(self.inFiles): >>> >>> self.progressBar.setValue(i + 1) >>> >>> newpath, newfname = rename_photo(self.inFolder, fname) >>> >>> newpath = path.join(self.outFolder, newpath) >>> >>> self.outFiles.append([fname, newpath, newfname]) >>> >>> s = fname + ' --> ' + self.outFolder + '\n' >>> >>> s += path.join(newpath, newfname).replace(self.outFolder, '') >>> >>> self.plainTextEdit_dest.appendPlainText(s) >>> >>> >>> >>> On 10/12/13 21:35, Sean Fisk wrote: >>>> >>>> Hi Janwillem, >>>> >>>> Are you running the “lengthy part that processes a files >>>> list” within the GUI thread? If so, you will probably see >>>> your GUI hang while this is happening (you won’t be able to >>>> click or do anything). In this case, you should consider >>>> running the processing in a different thread using QThread >>>> >>>> or QThreadPool >>>> . >>>> >>>> Can you post the relevant part of the code? >>>> >>>> Thanks, >>>> >>>> >>>> >>>> -- >>>> Sean Fisk >>>> >>>> >>>> On Tue, Dec 10, 2013 at 3:17 PM, Janwillem van Dijk >>>> > wrote: >>>> >>>> Hi, I have a PySide script that uses >>>> QFileDialog.getExistingDirectory(). After clicking the >>>> Open button the script proceeds with a lengthy part >>>> that processes a files list and writes to a >>>> QPlainTextEdit. Unfortunately the QFileDialog widget >>>> does only disappear after this processing is finished, >>>> hiding the QPlainTextEdit. >>>> >>>> How can I make that the QFileDialog widget is gone >>>> before the processing starts? >>>> >>>> Cheers, Janwillem >>>> >>>> >>>> >>>> >>>> _______________________________________________ >>>> PySide mailing list >>>> PySide at qt-project.org >>>> http://lists.qt-project.org/mailman/listinfo/pyside >>>> >>>> >>> >> >> > > I am on Linux (Ubuntu 13.10) and Python 3.2 developing using Spyder 2.3.0beta (I am a numpy scipy matplotlib user). I am not aware that gexiv2 is available for Windows so I cannot test that. -------------- next part -------------- An HTML attachment was scrubbed... URL: From frank at ohufx.com Wed Dec 11 22:45:57 2013 From: frank at ohufx.com (Frank Rueter | OHUfx) Date: Thu, 12 Dec 2013 10:45:57 +1300 Subject: [PySide] wait for QFileDialog to close In-Reply-To: References: <52A776CA.60704@xs4all.nl> <52A78016.4020008@xs4all.nl> <52A78AED.3070505@ohufx.com> <52A873BB.6040507@xs4all.nl> Message-ID: <52A8DD15.6040703@ohufx.com> Hi Sean, I totally agree that it shouldn't work, and I paid little attention to it as I just wanted to provide an example for the signal. I am on Kubuntu 12.10 using PySide 1.2.1. I just ran the code on an OSX box with an old PySide installation (1.0.9) and the progressbar didn't move there. I have a few simple apps to write which will involve proper use of progressbar to indicate background image processing, so I'm sure I will run into it again. Cheers, frank On 12/12/13 09:56, Sean Fisk wrote: > Janwillem, > > I'm glad you were able to able to figure out the problem. Sorry for my > red herrings! > > Frank, > > I thought about it, and I have no idea why the progress bar works fine > for you and not for me. It hangs for me, which is exactly what I > expected to happen. Maybe some platform difference? I'm on Mac OS 10.6 > with PySide 1.2.1. > > > -- > Sean Fisk > > > On Wed, Dec 11, 2013 at 9:16 AM, Janwillem van Dijk > > wrote: > > The solution Frank proposed yesterday works (after I found out > that you can get the output using selectedFiles()[0]). > No problems with the progressbar. > The actual processing can take a bit long because the exif's of > digital camera shots are analysed (GExiv2 for photos and exiftool > for movies ) and than copied to folders as > /camara_make/year/month/imagetype/yyyymmddhhmmss_fname. When > copying more than say 50 16MB raw photos the gui becomes blocked. > In other apps I indeed solved that with threading but, although > not elegant, I decided to live with that for this one. > Many thanks for teaching me this extra bit of Python. > Cheers, Janwillem > > > On 11/12/13 05:45, Sean Fisk wrote: >> >> Frank, >> >> Your example is a good demonstration of |QFileDialog|‘s signals. >> However, since the processing runs in the GUI thread, the >> progress bar is virtually useless as the GUI has no time to >> update it. It starts empty, the application hangs, and then it is >> filled when the processing is done. >> >> Janwillem, >> >> As I see it, if you would like a progress bar, you have three >> options: >> >> 1. Call |QCoreApplication.processEvents()| >> >> during your processing code. This is not always a great idea, >> and more of a hack than a solution. But it usually works. >> 2. Split your processing into chunks as in this example >> . >> However, the code is a bit convoluted and it still runs in >> the GUI thread. The whole page that contains that example is >> a great read for asynchronous programming. >> 3. Send your processing to a thread, and dispatch events from >> the thread indicating the progress. >> >> The first two solutions involve running processing code within >> the GUI thread. If any step of the processing takes longer than a >> second, then it’s probably not a good idea as the user will see >> the application hang. Here is an example implementation of the >> third solution: >> >> |#!/usr/bin/env python >> >> # Example: Asynchronously process a directory of files with a progress bar. >> >> import sys >> import os >> import time >> >> from PySideimport QtCore, QtGui >> >> class ProcessingThread(QtCore.QThread): >> # Fired when each file is processed. >> file_processed = QtCore.Signal(int, str) >> >> def __init__(self, parent=None): >> super(ProcessingThread, self).__init__(parent) >> self.files = [] >> >> def run(self): >> # Code that's run in the thread. >> for i, filenamein enumerate(self.files): >> # The actual code for one file goes here. Stubbed out with >> # time.sleep() for now. >> time.sleep(0.5) >> print 'Processed:', filename >> # Send update to the GUI thread. >> self.file_processed.emit(i +1, filename) >> >> class MyWidget(QtGui.QWidget): >> def __init__(self, parent=None): >> super(MyWidget, self).__init__(parent) >> >> # Setup UI. >> self._layout = QtGui.QVBoxLayout(self) >> self._button = QtGui.QPushButton('Open files...') >> self._progress = QtGui.QProgressBar() >> self._filelist = QtGui.QPlainTextEdit() >> self._layout.addWidget(self._button) >> self._layout.addWidget(self._filelist) >> self._layout.addWidget(self._progress) >> >> # Setup events. >> self._button.clicked.connect(self._button_clicked) >> >> # Create the thread. Note that this doesn't actually _start_ it. >> self._thread = ProcessingThread() >> self._thread.file_processed.connect(self._file_processed) >> >> # We need to wait for the thread before exiting. Either use this or >> # don't let the user close the window if processing is happening. See >> # the next method in this class. >> QtCore.QCoreApplication.instance().aboutToQuit.connect( >> self._thread.wait) >> >> # def closeEvent(self, event): >> # # This is an alternative to waiting for the threads. Just don't let >> # # the user close the window. >> # if self._thread.isRunning(): >> # QtGui.QMessageBox.critical( >> # self, 'Processing', >> # 'Cannot exit while processing is happening.') >> # event.ignore() >> # else: >> # event.accept() >> >> def _button_clicked(self): >> # If we are already running the processing, produce an error. >> if self._thread.isRunning(): >> QtGui.QMessageBox.critical( >> self,'Processing', >> 'Can only process one directory at a time.') >> return >> >> # Get the directory name from the user. >> dir_name = QtGui.QFileDialog.getExistingDirectory( >> parent=self, >> caption='Choose files...', >> dir=os.getcwd()) >> >> # Activate the main dialog as it will be deactivated for some reason >> # after the file dialog closes (at least on my machine). >> self.activateWindow() >> >> # Get the list of files in the directory and prime the progress bar. >> files = os.listdir(dir_name) >> >> # Set values for progress bar. >> self._progress.setRange(0, len(files)) >> self._progress.setValue(0) >> >> # Create and start the thread. >> self._thread.files = files >> self._thread.start() >> >> def _file_processed(self, num_files_processed, filename): >> # Called for each file that is processed. >> self._filelist.appendPlainText(filename) >> self._progress.setValue(num_files_processed) >> >> if __name__ =='__main__': >> app = QtGui.QApplication(sys.argv) >> w = MyWidget() >> w.show() >> w.raise_() >> raise SystemExit(app.exec_())| >> >> This is all fine, but it might not solve your original problem of >> the file dialog not closing. On my Mac, the file dialog is gone >> as soon as the call to |getExistingDirectory()| finishes. >> However, since I don’t have a runnable portion of your code, I >> can’t really test it. I would recommend attempting to run my >> example to see if it exhibits the same problem as your program. >> Hope this helps! >> >> Cheers, >> >> >> >> >> -- >> Sean Fisk >> >> >> On Tue, Dec 10, 2013 at 4:43 PM, Frank Rueter | OHUfx >> > wrote: >> >> Here is an example using signals/slots >> >> >> On 11/12/13 09:56, Janwillem van Dijk wrote: >>> >>> Here is the snippet: It reads the filenames in a folder and >>> determines new names for photo's based on the exif info. >>> >>> I apreciate that threading might be a solution but the >>> problem seems too simple for that. Can you give an example >>> on how to use the signal concept? >>> >>> >>> self.outFolder = QFileDialog.getExistingDirectory( >>> >>> caption='Destination folder', dir=self.defOutFolder) >>> >>> self.outFiles = [] >>> >>> if self.outFolder: >>> >>> self.outFolder = self.outFolder.replace('\\', '/') >>> >>> self.lineEdit_dest.setText(self.outFolder) >>> >>> self.progressBar.setRange(0, self.numFiles) >>> >>> for i, fname in enumerate(self.inFiles): >>> >>> self.progressBar.setValue(i + 1) >>> >>> newpath, newfname = rename_photo(self.inFolder, fname) >>> >>> newpath = path.join(self.outFolder, newpath) >>> >>> self.outFiles.append([fname, newpath, newfname]) >>> >>> s = fname + ' --> ' + self.outFolder + '\n' >>> >>> s += path.join(newpath, newfname).replace(self.outFolder, '') >>> >>> self.plainTextEdit_dest.appendPlainText(s) >>> >>> >>> >>> On 10/12/13 21:35, Sean Fisk wrote: >>>> >>>> Hi Janwillem, >>>> >>>> Are you running the “lengthy part that processes a files >>>> list” within the GUI thread? If so, you will probably see >>>> your GUI hang while this is happening (you won’t be able to >>>> click or do anything). In this case, you should consider >>>> running the processing in a different thread using QThread >>>> >>>> or QThreadPool >>>> . >>>> >>>> Can you post the relevant part of the code? >>>> >>>> Thanks, >>>> >>>> >>>> >>>> -- >>>> Sean Fisk >>>> >>>> >>>> On Tue, Dec 10, 2013 at 3:17 PM, Janwillem van Dijk >>>> > wrote: >>>> >>>> Hi, I have a PySide script that uses >>>> QFileDialog.getExistingDirectory(). After clicking the >>>> Open button the script proceeds with a lengthy part >>>> that processes a files list and writes to a >>>> QPlainTextEdit. Unfortunately the QFileDialog widget >>>> does only disappear after this processing is finished, >>>> hiding the QPlainTextEdit. >>>> >>>> How can I make that the QFileDialog widget is gone >>>> before the processing starts? >>>> >>>> Cheers, Janwillem >>>> >>>> >>>> >>>> >>>> _______________________________________________ >>>> PySide mailing list >>>> PySide at qt-project.org >>>> http://lists.qt-project.org/mailman/listinfo/pyside >>>> >>>> >>> >> >> > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From sean at seanfisk.com Thu Dec 12 00:07:51 2013 From: sean at seanfisk.com (Sean Fisk) Date: Wed, 11 Dec 2013 18:07:51 -0500 Subject: [PySide] wait for QFileDialog to close In-Reply-To: <52A8DD15.6040703@ohufx.com> References: <52A776CA.60704@xs4all.nl> <52A78016.4020008@xs4all.nl> <52A78AED.3070505@ohufx.com> <52A873BB.6040507@xs4all.nl> <52A8DD15.6040703@ohufx.com> Message-ID: Frank, Understood. I'm going to try your example on CentOS 6.4 with PySide 1.2.1 and see what happens. Let me know what happens with future progress bars. I'm going to start doing a lot of asynchronous stuff soon, so it would be helpful to know. Thanks, -- Sean Fisk On Wed, Dec 11, 2013 at 4:45 PM, Frank Rueter | OHUfx wrote: > Hi Sean, > > I totally agree that it shouldn't work, and I paid little attention to it > as I just wanted to provide an example for the signal. > > I am on Kubuntu 12.10 using PySide 1.2.1. > I just ran the code on an OSX box with an old PySide installation (1.0.9) > and the progressbar didn't move there. > > I have a few simple apps to write which will involve proper use of > progressbar to indicate background image processing, so I'm sure I will run > into it again. > > > Cheers, > frank > > > > On 12/12/13 09:56, Sean Fisk wrote: > > Janwillem, > > I'm glad you were able to able to figure out the problem. Sorry for my > red herrings! > > Frank, > > I thought about it, and I have no idea why the progress bar works fine > for you and not for me. It hangs for me, which is exactly what I expected > to happen. Maybe some platform difference? I'm on Mac OS 10.6 with PySide > 1.2.1. > > > -- > Sean Fisk > > > On Wed, Dec 11, 2013 at 9:16 AM, Janwillem van Dijk wrote: > >> The solution Frank proposed yesterday works (after I found out that you >> can get the output using selectedFiles()[0]). >> No problems with the progressbar. >> The actual processing can take a bit long because the exif's of digital >> camera shots are analysed (GExiv2 for photos and exiftool for movies ) and >> than copied to folders as >> /camara_make/year/month/imagetype/yyyymmddhhmmss_fname. When copying more >> than say 50 16MB raw photos the gui becomes blocked. In other apps I indeed >> solved that with threading but, although not elegant, I decided to live >> with that for this one. >> Many thanks for teaching me this extra bit of Python. >> Cheers, Janwillem >> >> >> On 11/12/13 05:45, Sean Fisk wrote: >> >> Frank, >> >> Your example is a good demonstration of QFileDialog‘s signals. However, >> since the processing runs in the GUI thread, the progress bar is virtually >> useless as the GUI has no time to update it. It starts empty, the >> application hangs, and then it is filled when the processing is done. >> >> Janwillem, >> >> As I see it, if you would like a progress bar, you have three options: >> >> 1. Call QCoreApplication.processEvents()during your processing code. This is not always a great idea, and more of a >> hack than a solution. But it usually works. >> 2. Split your processing into chunks as in this example. >> However, the code is a bit convoluted and it still runs in the GUI thread. >> The whole page that contains that example is a great read for asynchronous >> programming. >> 3. Send your processing to a thread, and dispatch events from the >> thread indicating the progress. >> >> The first two solutions involve running processing code within the GUI >> thread. If any step of the processing takes longer than a second, then it’s >> probably not a good idea as the user will see the application hang. Here is >> an example implementation of the third solution: >> >> #!/usr/bin/env python >> # Example: Asynchronously process a directory of files with a progress bar. >> import sysimport osimport time >> from PySide import QtCore, QtGui >> class ProcessingThread(QtCore.QThread): >> # Fired when each file is processed. >> file_processed = QtCore.Signal(int, str) >> >> def __init__(self, parent=None): >> super(ProcessingThread, self).__init__(parent) >> self.files = [] >> >> def run(self): >> # Code that's run in the thread. >> for i, filename in enumerate(self.files): >> # The actual code for one file goes here. Stubbed out with >> # time.sleep() for now. >> time.sleep(0.5) >> print 'Processed:', filename >> # Send update to the GUI thread. >> self.file_processed.emit(i + 1, filename) >> class MyWidget(QtGui.QWidget): >> def __init__(self, parent=None): >> super(MyWidget, self).__init__(parent) >> >> # Setup UI. >> self._layout = QtGui.QVBoxLayout(self) >> self._button = QtGui.QPushButton('Open files...') >> self._progress = QtGui.QProgressBar() >> self._filelist = QtGui.QPlainTextEdit() >> self._layout.addWidget(self._button) >> self._layout.addWidget(self._filelist) >> self._layout.addWidget(self._progress) >> >> # Setup events. >> self._button.clicked.connect(self._button_clicked) >> >> # Create the thread. Note that this doesn't actually _start_ it. >> self._thread = ProcessingThread() >> self._thread.file_processed.connect(self._file_processed) >> >> # We need to wait for the thread before exiting. Either use this or >> # don't let the user close the window if processing is happening. See >> # the next method in this class. >> QtCore.QCoreApplication.instance().aboutToQuit.connect( >> self._thread.wait) >> >> # def closeEvent(self, event): >> # # This is an alternative to waiting for the threads. Just don't let >> # # the user close the window. >> # if self._thread.isRunning(): >> # QtGui.QMessageBox.critical( >> # self, 'Processing', >> # 'Cannot exit while processing is happening.') >> # event.ignore() >> # else: >> # event.accept() >> >> def _button_clicked(self): >> # If we are already running the processing, produce an error. >> if self._thread.isRunning(): >> QtGui.QMessageBox.critical( >> self, 'Processing', >> 'Can only process one directory at a time.') >> return >> >> # Get the directory name from the user. >> dir_name = QtGui.QFileDialog.getExistingDirectory( >> parent=self, >> caption='Choose files...', >> dir=os.getcwd()) >> >> # Activate the main dialog as it will be deactivated for some reason >> # after the file dialog closes (at least on my machine). >> self.activateWindow() >> >> # Get the list of files in the directory and prime the progress bar. >> files = os.listdir(dir_name) >> >> # Set values for progress bar. >> self._progress.setRange(0, len(files)) >> self._progress.setValue(0) >> >> # Create and start the thread. >> self._thread.files = files >> self._thread.start() >> >> def _file_processed(self, num_files_processed, filename): >> # Called for each file that is processed. >> self._filelist.appendPlainText(filename) >> self._progress.setValue(num_files_processed) >> if __name__ == '__main__': >> app = QtGui.QApplication(sys.argv) >> w = MyWidget() >> w.show() >> w.raise_() >> raise SystemExit(app.exec_()) >> >> This is all fine, but it might not solve your original problem of the >> file dialog not closing. On my Mac, the file dialog is gone as soon as the >> call to getExistingDirectory() finishes. However, since I don’t have a >> runnable portion of your code, I can’t really test it. I would recommend >> attempting to run my example to see if it exhibits the same problem as your >> program. Hope this helps! >> >> Cheers, >> >> >> >> -- >> Sean Fisk >> >> >> On Tue, Dec 10, 2013 at 4:43 PM, Frank Rueter | OHUfx wrote: >> >>> Here is an example using signals/slots >>> >>> >>> On 11/12/13 09:56, Janwillem van Dijk wrote: >>> >>> Here is the snippet: It reads the filenames in a folder and determines >>> new names for photo's based on the exif info. >>> >>> I apreciate that threading might be a solution but the problem seems too >>> simple for that. Can you give an example on how to use the signal concept? >>> >>> >>> self.outFolder = QFileDialog.getExistingDirectory( >>> >>> caption='Destination folder', dir=self.defOutFolder) >>> >>> self.outFiles = [] >>> >>> if self.outFolder: >>> >>> self.outFolder = self.outFolder.replace('\\', '/') >>> >>> self.lineEdit_dest.setText(self.outFolder) >>> >>> self.progressBar.setRange(0, self.numFiles) >>> >>> for i, fname in enumerate(self.inFiles): >>> >>> self.progressBar.setValue(i + 1) >>> >>> newpath, newfname = rename_photo(self.inFolder, fname) >>> >>> newpath = path.join(self.outFolder, newpath) >>> >>> self.outFiles.append([fname, newpath, newfname]) >>> >>> s = fname + ' --> ' + self.outFolder + '\n' >>> >>> s += path.join(newpath, newfname).replace(self.outFolder, '') >>> >>> self.plainTextEdit_dest.appendPlainText(s) >>> >>> >>> >>> On 10/12/13 21:35, Sean Fisk wrote: >>> >>> Hi Janwillem, >>> >>> Are you running the “lengthy part that processes a files list” within >>> the GUI thread? If so, you will probably see your GUI hang while this is >>> happening (you won’t be able to click or do anything). In this case, you >>> should consider running the processing in a different thread using >>> QThreador >>> QThreadPool >>> . >>> >>> Can you post the relevant part of the code? >>> >>> Thanks, >>> >>> >>> -- >>> Sean Fisk >>> >>> >>> On Tue, Dec 10, 2013 at 3:17 PM, Janwillem van Dijk < >>> jwevandijk at xs4all.nl> wrote: >>> >>>> Hi, I have a PySide script that uses >>>> QFileDialog.getExistingDirectory(). After clicking the Open button the >>>> script proceeds with a lengthy part that processes a files list and writes >>>> to a QPlainTextEdit. Unfortunately the QFileDialog widget does only >>>> disappear after this processing is finished, hiding the QPlainTextEdit. >>>> >>>> How can I make that the QFileDialog widget is gone before the >>>> processing starts? >>>> >>>> Cheers, Janwillem >>>> >>>> >>>> >>>> >>>> _______________________________________________ >>>> PySide mailing list >>>> PySide at qt-project.org >>>> http://lists.qt-project.org/mailman/listinfo/pyside >>>> >>>> >>> >>> >>> >> >> > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From frank at ohufx.com Thu Dec 12 00:16:36 2013 From: frank at ohufx.com (Frank Rueter | OHUfx) Date: Thu, 12 Dec 2013 12:16:36 +1300 Subject: [PySide] wait for QFileDialog to close In-Reply-To: References: <52A776CA.60704@xs4all.nl> <52A78016.4020008@xs4all.nl> <52A78AED.3070505@ohufx.com> <52A873BB.6040507@xs4all.nl> <52A8DD15.6040703@ohufx.com> Message-ID: <52A8F254.5020005@ohufx.com> Ok, will report back if I stumble across anything interesting. For now I will just assume that my example simply shouldn't work :-D On 12/12/13 12:07, Sean Fisk wrote: > Frank, > > Understood. I'm going to try your example on CentOS 6.4 with PySide > 1.2.1 and see what happens. Let me know what happens with future > progress bars. I'm going to start doing a lot of asynchronous stuff > soon, so it would be helpful to know. > > Thanks, > > > -- > Sean Fisk > > > On Wed, Dec 11, 2013 at 4:45 PM, Frank Rueter | OHUfx > wrote: > > Hi Sean, > > I totally agree that it shouldn't work, and I paid little > attention to it as I just wanted to provide an example for the signal. > > I am on Kubuntu 12.10 using PySide 1.2.1. > I just ran the code on an OSX box with an old PySide installation > (1.0.9) and the progressbar didn't move there. > > I have a few simple apps to write which will involve proper use of > progressbar to indicate background image processing, so I'm sure I > will run into it again. > > > Cheers, > frank > > > > On 12/12/13 09:56, Sean Fisk wrote: >> Janwillem, >> >> I'm glad you were able to able to figure out the problem. Sorry >> for my red herrings! >> >> Frank, >> >> I thought about it, and I have no idea why the progress bar works >> fine for you and not for me. It hangs for me, which is exactly >> what I expected to happen. Maybe some platform difference? I'm on >> Mac OS 10.6 with PySide 1.2.1. >> >> >> -- >> Sean Fisk >> >> >> On Wed, Dec 11, 2013 at 9:16 AM, Janwillem van Dijk >> > wrote: >> >> The solution Frank proposed yesterday works (after I found >> out that you can get the output using selectedFiles()[0]). >> No problems with the progressbar. >> The actual processing can take a bit long because the exif's >> of digital camera shots are analysed (GExiv2 for photos and >> exiftool for movies ) and than copied to folders as >> /camara_make/year/month/imagetype/yyyymmddhhmmss_fname. When >> copying more than say 50 16MB raw photos the gui becomes >> blocked. In other apps I indeed solved that with threading >> but, although not elegant, I decided to live with that for >> this one. >> Many thanks for teaching me this extra bit of Python. >> Cheers, Janwillem >> >> >> On 11/12/13 05:45, Sean Fisk wrote: >>> >>> Frank, >>> >>> Your example is a good demonstration of |QFileDialog|‘s >>> signals. However, since the processing runs in the GUI >>> thread, the progress bar is virtually useless as the GUI has >>> no time to update it. It starts empty, the application >>> hangs, and then it is filled when the processing is done. >>> >>> Janwillem, >>> >>> As I see it, if you would like a progress bar, you have >>> three options: >>> >>> 1. Call |QCoreApplication.processEvents()| >>> >>> during your processing code. This is not always a great >>> idea, and more of a hack than a solution. But it usually >>> works. >>> 2. Split your processing into chunks as in this example >>> . >>> However, the code is a bit convoluted and it still runs >>> in the GUI thread. The whole page that contains that >>> example is a great read for asynchronous programming. >>> 3. Send your processing to a thread, and dispatch events >>> from the thread indicating the progress. >>> >>> The first two solutions involve running processing code >>> within the GUI thread. If any step of the processing takes >>> longer than a second, then it’s probably not a good idea as >>> the user will see the application hang. Here is an example >>> implementation of the third solution: >>> >>> |#!/usr/bin/env python >>> >>> # Example: Asynchronously process a directory of files with a progress bar. >>> >>> import sys >>> import os >>> import time >>> >>> from PySideimport QtCore, QtGui >>> >>> class ProcessingThread(QtCore.QThread): >>> # Fired when each file is processed. >>> file_processed = QtCore.Signal(int, str) >>> >>> def __init__(self, parent=None): >>> super(ProcessingThread, self).__init__(parent) >>> self.files = [] >>> >>> def run(self): >>> # Code that's run in the thread. >>> for i, filenamein enumerate(self.files): >>> # The actual code for one file goes here. Stubbed out with >>> # time.sleep() for now. >>> time.sleep(0.5) >>> print 'Processed:', filename >>> # Send update to the GUI thread. >>> self.file_processed.emit(i +1, filename) >>> >>> class MyWidget(QtGui.QWidget): >>> def __init__(self, parent=None): >>> super(MyWidget, self).__init__(parent) >>> >>> # Setup UI. >>> self._layout = QtGui.QVBoxLayout(self) >>> self._button = QtGui.QPushButton('Open files...') >>> self._progress = QtGui.QProgressBar() >>> self._filelist = QtGui.QPlainTextEdit() >>> self._layout.addWidget(self._button) >>> self._layout.addWidget(self._filelist) >>> self._layout.addWidget(self._progress) >>> >>> # Setup events. >>> self._button.clicked.connect(self._button_clicked) >>> >>> # Create the thread. Note that this doesn't actually _start_ it. >>> self._thread = ProcessingThread() >>> self._thread.file_processed.connect(self._file_processed) >>> >>> # We need to wait for the thread before exiting. Either use this or >>> # don't let the user close the window if processing is happening. See >>> # the next method in this class. >>> QtCore.QCoreApplication.instance().aboutToQuit.connect( >>> self._thread.wait) >>> >>> # def closeEvent(self, event): >>> # # This is an alternative to waiting for the threads. Just don't let >>> # # the user close the window. >>> # if self._thread.isRunning(): >>> # QtGui.QMessageBox.critical( >>> # self, 'Processing', >>> # 'Cannot exit while processing is happening.') >>> # event.ignore() >>> # else: >>> # event.accept() >>> >>> def _button_clicked(self): >>> # If we are already running the processing, produce an error. >>> if self._thread.isRunning(): >>> QtGui.QMessageBox.critical( >>> self,'Processing', >>> 'Can only process one directory at a time.') >>> return >>> >>> # Get the directory name from the user. >>> dir_name = QtGui.QFileDialog.getExistingDirectory( >>> parent=self, >>> caption='Choose files...', >>> dir=os.getcwd()) >>> >>> # Activate the main dialog as it will be deactivated for some reason >>> # after the file dialog closes (at least on my machine). >>> self.activateWindow() >>> >>> # Get the list of files in the directory and prime the progress bar. >>> files = os.listdir(dir_name) >>> >>> # Set values for progress bar. >>> self._progress.setRange(0, len(files)) >>> self._progress.setValue(0) >>> >>> # Create and start the thread. >>> self._thread.files = files >>> self._thread.start() >>> >>> def _file_processed(self, num_files_processed, filename): >>> # Called for each file that is processed. >>> self._filelist.appendPlainText(filename) >>> self._progress.setValue(num_files_processed) >>> >>> if __name__ =='__main__': >>> app = QtGui.QApplication(sys.argv) >>> w = MyWidget() >>> w.show() >>> w.raise_() >>> raise SystemExit(app.exec_())| >>> >>> This is all fine, but it might not solve your original >>> problem of the file dialog not closing. On my Mac, the file >>> dialog is gone as soon as the call to >>> |getExistingDirectory()| finishes. However, since I don’t >>> have a runnable portion of your code, I can’t really test >>> it. I would recommend attempting to run my example to see if >>> it exhibits the same problem as your program. Hope this helps! >>> >>> Cheers, >>> >>> >>> >>> >>> -- >>> Sean Fisk >>> >>> >>> On Tue, Dec 10, 2013 at 4:43 PM, Frank Rueter | OHUfx >>> > wrote: >>> >>> Here is an example using signals/slots >>> >>> >>> On 11/12/13 09:56, Janwillem van Dijk wrote: >>>> >>>> Here is the snippet: It reads the filenames in a folder >>>> and determines new names for photo's based on the exif >>>> info. >>>> >>>> I apreciate that threading might be a solution but the >>>> problem seems too simple for that. Can you give an >>>> example on how to use the signal concept? >>>> >>>> >>>> self.outFolder = QFileDialog.getExistingDirectory( >>>> >>>> caption='Destination folder', dir=self.defOutFolder) >>>> >>>> self.outFiles = [] >>>> >>>> if self.outFolder: >>>> >>>> self.outFolder = self.outFolder.replace('\\', '/') >>>> >>>> self.lineEdit_dest.setText(self.outFolder) >>>> >>>> self.progressBar.setRange(0, self.numFiles) >>>> >>>> for i, fname in enumerate(self.inFiles): >>>> >>>> self.progressBar.setValue(i + 1) >>>> >>>> newpath, newfname = rename_photo(self.inFolder, fname) >>>> >>>> newpath = path.join(self.outFolder, newpath) >>>> >>>> self.outFiles.append([fname, newpath, newfname]) >>>> >>>> s = fname + ' --> ' + self.outFolder + '\n' >>>> >>>> s += path.join(newpath, >>>> newfname).replace(self.outFolder, '') >>>> >>>> self.plainTextEdit_dest.appendPlainText(s) >>>> >>>> >>>> >>>> On 10/12/13 21:35, Sean Fisk wrote: >>>>> >>>>> Hi Janwillem, >>>>> >>>>> Are you running the “lengthy part that processes a >>>>> files list” within the GUI thread? If so, you will >>>>> probably see your GUI hang while this is happening >>>>> (you won’t be able to click or do anything). In this >>>>> case, you should consider running the processing in a >>>>> different thread using QThread >>>>> >>>>> or QThreadPool >>>>> . >>>>> >>>>> Can you post the relevant part of the code? >>>>> >>>>> Thanks, >>>>> >>>>> >>>>> >>>>> -- >>>>> Sean Fisk >>>>> >>>>> >>>>> On Tue, Dec 10, 2013 at 3:17 PM, Janwillem van Dijk >>>>> > >>>>> wrote: >>>>> >>>>> Hi, I have a PySide script that uses >>>>> QFileDialog.getExistingDirectory(). After clicking >>>>> the Open button the script proceeds with a lengthy >>>>> part that processes a files list and writes to a >>>>> QPlainTextEdit. Unfortunately the QFileDialog >>>>> widget does only disappear after this processing >>>>> is finished, hiding the QPlainTextEdit. >>>>> >>>>> How can I make that the QFileDialog widget is gone >>>>> before the processing starts? >>>>> >>>>> Cheers, Janwillem >>>>> >>>>> >>>>> >>>>> >>>>> _______________________________________________ >>>>> PySide mailing list >>>>> PySide at qt-project.org >>>>> http://lists.qt-project.org/mailman/listinfo/pyside >>>>> >>>>> >>>> >>> >>> >> >> > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From sean at seanfisk.com Thu Dec 12 00:37:10 2013 From: sean at seanfisk.com (Sean Fisk) Date: Wed, 11 Dec 2013 18:37:10 -0500 Subject: [PySide] wait for QFileDialog to close In-Reply-To: <52A8F254.5020005@ohufx.com> References: <52A776CA.60704@xs4all.nl> <52A78016.4020008@xs4all.nl> <52A78AED.3070505@ohufx.com> <52A873BB.6040507@xs4all.nl> <52A8DD15.6040703@ohufx.com> <52A8F254.5020005@ohufx.com> Message-ID: I just tried it on CentOS with PySide 1.2.1. The progress bar does indeed work. However, I do see some visual glitches: the layout doesn’t readjust if the window is resized; the button sometimes disappears halfway or fully; the button can’t be clicked. Throwing in a call to QtGui.QApplication.processEvents() before time.sleep() helps the situation, but the response is laggy and sluggish because the GUI is still only able to update every half-second. While threads are “evil” in many ways, I do think that for delays of half a second or greater they are a good solution. -- Sean Fisk On Wed, Dec 11, 2013 at 6:16 PM, Frank Rueter | OHUfx wrote: > Ok, will report back if I stumble across anything interesting. For now I > will just assume that my example simply shouldn't work :-D > > > > On 12/12/13 12:07, Sean Fisk wrote: > > Frank, > > Understood. I'm going to try your example on CentOS 6.4 with PySide > 1.2.1 and see what happens. Let me know what happens with future progress > bars. I'm going to start doing a lot of asynchronous stuff soon, so it > would be helpful to know. > > Thanks, > > > -- > Sean Fisk > > > On Wed, Dec 11, 2013 at 4:45 PM, Frank Rueter | OHUfx wrote: > >> Hi Sean, >> >> I totally agree that it shouldn't work, and I paid little attention to it >> as I just wanted to provide an example for the signal. >> >> I am on Kubuntu 12.10 using PySide 1.2.1. >> I just ran the code on an OSX box with an old PySide installation (1.0.9) >> and the progressbar didn't move there. >> >> I have a few simple apps to write which will involve proper use of >> progressbar to indicate background image processing, so I'm sure I will run >> into it again. >> >> >> Cheers, >> frank >> >> >> >> On 12/12/13 09:56, Sean Fisk wrote: >> >> Janwillem, >> >> I'm glad you were able to able to figure out the problem. Sorry for my >> red herrings! >> >> Frank, >> >> I thought about it, and I have no idea why the progress bar works fine >> for you and not for me. It hangs for me, which is exactly what I expected >> to happen. Maybe some platform difference? I'm on Mac OS 10.6 with PySide >> 1.2.1. >> >> >> -- >> Sean Fisk >> >> >> On Wed, Dec 11, 2013 at 9:16 AM, Janwillem van Dijk > > wrote: >> >>> The solution Frank proposed yesterday works (after I found out that >>> you can get the output using selectedFiles()[0]). >>> No problems with the progressbar. >>> The actual processing can take a bit long because the exif's of digital >>> camera shots are analysed (GExiv2 for photos and exiftool for movies ) and >>> than copied to folders as >>> /camara_make/year/month/imagetype/yyyymmddhhmmss_fname. When copying more >>> than say 50 16MB raw photos the gui becomes blocked. In other apps I indeed >>> solved that with threading but, although not elegant, I decided to live >>> with that for this one. >>> Many thanks for teaching me this extra bit of Python. >>> Cheers, Janwillem >>> >>> >>> On 11/12/13 05:45, Sean Fisk wrote: >>> >>> Frank, >>> >>> Your example is a good demonstration of QFileDialog‘s signals. However, >>> since the processing runs in the GUI thread, the progress bar is virtually >>> useless as the GUI has no time to update it. It starts empty, the >>> application hangs, and then it is filled when the processing is done. >>> >>> Janwillem, >>> >>> As I see it, if you would like a progress bar, you have three options: >>> >>> 1. Call QCoreApplication.processEvents()during your processing code. This is not always a great idea, and more of a >>> hack than a solution. But it usually works. >>> 2. Split your processing into chunks as in this example. >>> However, the code is a bit convoluted and it still runs in the GUI thread. >>> The whole page that contains that example is a great read for asynchronous >>> programming. >>> 3. Send your processing to a thread, and dispatch events from the >>> thread indicating the progress. >>> >>> The first two solutions involve running processing code within the GUI >>> thread. If any step of the processing takes longer than a second, then it’s >>> probably not a good idea as the user will see the application hang. Here is >>> an example implementation of the third solution: >>> >>> #!/usr/bin/env python >>> # Example: Asynchronously process a directory of files with a progress bar. >>> import sysimport osimport time >>> from PySide import QtCore, QtGui >>> class ProcessingThread(QtCore.QThread): >>> # Fired when each file is processed. >>> file_processed = QtCore.Signal(int, str) >>> >>> def __init__(self, parent=None): >>> super(ProcessingThread, self).__init__(parent) >>> self.files = [] >>> >>> def run(self): >>> # Code that's run in the thread. >>> for i, filename in enumerate(self.files): >>> # The actual code for one file goes here. Stubbed out with >>> # time.sleep() for now. >>> time.sleep(0.5) >>> print 'Processed:', filename >>> # Send update to the GUI thread. >>> self.file_processed.emit(i + 1, filename) >>> class MyWidget(QtGui.QWidget): >>> def __init__(self, parent=None): >>> super(MyWidget, self).__init__(parent) >>> >>> # Setup UI. >>> self._layout = QtGui.QVBoxLayout(self) >>> self._button = QtGui.QPushButton('Open files...') >>> self._progress = QtGui.QProgressBar() >>> self._filelist = QtGui.QPlainTextEdit() >>> self._layout.addWidget(self._button) >>> self._layout.addWidget(self._filelist) >>> self._layout.addWidget(self._progress) >>> >>> # Setup events. >>> self._button.clicked.connect(self._button_clicked) >>> >>> # Create the thread. Note that this doesn't actually _start_ it. >>> self._thread = ProcessingThread() >>> self._thread.file_processed.connect(self._file_processed) >>> >>> # We need to wait for the thread before exiting. Either use this or >>> # don't let the user close the window if processing is happening. See >>> # the next method in this class. >>> QtCore.QCoreApplication.instance().aboutToQuit.connect( >>> self._thread.wait) >>> >>> # def closeEvent(self, event): >>> # # This is an alternative to waiting for the threads. Just don't let >>> # # the user close the window. >>> # if self._thread.isRunning(): >>> # QtGui.QMessageBox.critical( >>> # self, 'Processing', >>> # 'Cannot exit while processing is happening.') >>> # event.ignore() >>> # else: >>> # event.accept() >>> >>> def _button_clicked(self): >>> # If we are already running the processing, produce an error. >>> if self._thread.isRunning(): >>> QtGui.QMessageBox.critical( >>> self, 'Processing', >>> 'Can only process one directory at a time.') >>> return >>> >>> # Get the directory name from the user. >>> dir_name = QtGui.QFileDialog.getExistingDirectory( >>> parent=self, >>> caption='Choose files...', >>> dir=os.getcwd()) >>> >>> # Activate the main dialog as it will be deactivated for some reason >>> # after the file dialog closes (at least on my machine). >>> self.activateWindow() >>> >>> # Get the list of files in the directory and prime the progress bar. >>> files = os.listdir(dir_name) >>> >>> # Set values for progress bar. >>> self._progress.setRange(0, len(files)) >>> self._progress.setValue(0) >>> >>> # Create and start the thread. >>> self._thread.files = files >>> self._thread.start() >>> >>> def _file_processed(self, num_files_processed, filename): >>> # Called for each file that is processed. >>> self._filelist.appendPlainText(filename) >>> self._progress.setValue(num_files_processed) >>> if __name__ == '__main__': >>> app = QtGui.QApplication(sys.argv) >>> w = MyWidget() >>> w.show() >>> w.raise_() >>> raise SystemExit(app.exec_()) >>> >>> This is all fine, but it might not solve your original problem of the >>> file dialog not closing. On my Mac, the file dialog is gone as soon as the >>> call to getExistingDirectory() finishes. However, since I don’t have a >>> runnable portion of your code, I can’t really test it. I would recommend >>> attempting to run my example to see if it exhibits the same problem as your >>> program. Hope this helps! >>> >>> Cheers, >>> >>> >>> >>> -- >>> Sean Fisk >>> >>> >>> On Tue, Dec 10, 2013 at 4:43 PM, Frank Rueter | OHUfx wrote: >>> >>>> Here is an example using signals/slots >>>> >>>> >>>> On 11/12/13 09:56, Janwillem van Dijk wrote: >>>> >>>> Here is the snippet: It reads the filenames in a folder and >>>> determines new names for photo's based on the exif info. >>>> >>>> I apreciate that threading might be a solution but the problem seems >>>> too simple for that. Can you give an example on how to use the signal >>>> concept? >>>> >>>> >>>> self.outFolder = QFileDialog.getExistingDirectory( >>>> >>>> caption='Destination folder', dir=self.defOutFolder) >>>> >>>> self.outFiles = [] >>>> >>>> if self.outFolder: >>>> >>>> self.outFolder = self.outFolder.replace('\\', '/') >>>> >>>> self.lineEdit_dest.setText(self.outFolder) >>>> >>>> self.progressBar.setRange(0, self.numFiles) >>>> >>>> for i, fname in enumerate(self.inFiles): >>>> >>>> self.progressBar.setValue(i + 1) >>>> >>>> newpath, newfname = rename_photo(self.inFolder, fname) >>>> >>>> newpath = path.join(self.outFolder, newpath) >>>> >>>> self.outFiles.append([fname, newpath, newfname]) >>>> >>>> s = fname + ' --> ' + self.outFolder + '\n' >>>> >>>> s += path.join(newpath, newfname).replace(self.outFolder, '') >>>> >>>> self.plainTextEdit_dest.appendPlainText(s) >>>> >>>> >>>> >>>> On 10/12/13 21:35, Sean Fisk wrote: >>>> >>>> Hi Janwillem, >>>> >>>> Are you running the “lengthy part that processes a files list” within >>>> the GUI thread? If so, you will probably see your GUI hang while this is >>>> happening (you won’t be able to click or do anything). In this case, you >>>> should consider running the processing in a different thread using >>>> QThreador >>>> QThreadPool >>>> . >>>> >>>> Can you post the relevant part of the code? >>>> >>>> Thanks, >>>> >>>> >>>> -- >>>> Sean Fisk >>>> >>>> >>>> On Tue, Dec 10, 2013 at 3:17 PM, Janwillem van Dijk < >>>> jwevandijk at xs4all.nl> wrote: >>>> >>>>> Hi, I have a PySide script that uses >>>>> QFileDialog.getExistingDirectory(). After clicking the Open button the >>>>> script proceeds with a lengthy part that processes a files list and writes >>>>> to a QPlainTextEdit. Unfortunately the QFileDialog widget does only >>>>> disappear after this processing is finished, hiding the QPlainTextEdit. >>>>> >>>>> How can I make that the QFileDialog widget is gone before the >>>>> processing starts? >>>>> >>>>> Cheers, Janwillem >>>>> >>>>> >>>>> >>>>> >>>>> _______________________________________________ >>>>> PySide mailing list >>>>> PySide at qt-project.org >>>>> http://lists.qt-project.org/mailman/listinfo/pyside >>>>> >>>>> >>>> >>>> >>>> >>> >>> >> >> > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From matthew.woehlke at kitware.com Thu Dec 12 01:02:21 2013 From: matthew.woehlke at kitware.com (Matthew Woehlke) Date: Wed, 11 Dec 2013 19:02:21 -0500 Subject: [PySide] wait for QFileDialog to close In-Reply-To: References: <52A776CA.60704@xs4all.nl> <52A78016.4020008@xs4all.nl> <52A78AED.3070505@ohufx.com> <52A873BB.6040507@xs4all.nl> <52A8DD15.6040703@ohufx.com> <52A8F254.5020005@ohufx.com> Message-ID: On 2013-12-11 18:37, Sean Fisk wrote: > I just tried it on CentOS with PySide 1.2.1. The progress bar does indeed > work. However, I do see some visual glitches: the layout doesn’t readjust > if the window is resized; the button sometimes disappears halfway or fully; > the button can’t be clicked. This sounds like your environment is coincidentally performing some update operations synchronously that usually are deferred. This probably explains why you see different behavior depending on the platform. I've seen similar artifacts before, e.g. code in projects I work on (not written by me :P) that shows a 'please wait' dialog before going off and blocking the GUI thread for some time that "work" (i.e. show up) on some machines and not on others. There are probably a number of factors affecting this; OS is an obvious one, but widget style could also come into play and I wouldn't be surprised if even system load can have an effect. IOW, I wouldn't get too hung up on why it sometimes works, and just write it up as being unreliable (i.e. something to avoid or work around). p.s. You really should never, ever block the GUI thread for more than ~250ms ;-). Threads (or QtConcurrent) are good for "slow" tasks, or else make sure you are allowing the event loop to run (i.e. processEvents) every now and then. -- Matthew From frank at ohufx.com Thu Dec 12 03:12:48 2013 From: frank at ohufx.com (Frank Rueter | OHUfx) Date: Thu, 12 Dec 2013 15:12:48 +1300 Subject: [PySide] wait for QFileDialog to close In-Reply-To: References: <52A776CA.60704@xs4all.nl> <52A78016.4020008@xs4all.nl> <52A78AED.3070505@ohufx.com> <52A873BB.6040507@xs4all.nl> <52A8DD15.6040703@ohufx.com> <52A8F254.5020005@ohufx.com> Message-ID: <52A91BA0.6040101@ohufx.com> Thanks for the update Sean! On 12/12/13 12:37, Sean Fisk wrote: > > I just tried it on CentOS with PySide 1.2.1. The progress bar does > indeed work. However, I do see some visual glitches: the layout > doesn’t readjust if the window is resized; the button sometimes > disappears halfway or fully; the button can’t be clicked. Throwing in > a call to |QtGui.QApplication.processEvents()| before |time.sleep()| > helps the situation, but the response is laggy and sluggish because > the GUI is still only able to update every half-second. > > While threads are “evil” in many ways, I do think that for delays of > half a second or greater they are a good solution. > > > > -- > Sean Fisk > > > On Wed, Dec 11, 2013 at 6:16 PM, Frank Rueter | OHUfx > wrote: > > Ok, will report back if I stumble across anything interesting. For > now I will just assume that my example simply shouldn't work :-D > > > > On 12/12/13 12:07, Sean Fisk wrote: >> Frank, >> >> Understood. I'm going to try your example on CentOS 6.4 with >> PySide 1.2.1 and see what happens. Let me know what happens with >> future progress bars. I'm going to start doing a lot of >> asynchronous stuff soon, so it would be helpful to know. >> >> Thanks, >> >> >> -- >> Sean Fisk >> >> >> On Wed, Dec 11, 2013 at 4:45 PM, Frank Rueter | OHUfx >> > wrote: >> >> Hi Sean, >> >> I totally agree that it shouldn't work, and I paid little >> attention to it as I just wanted to provide an example for >> the signal. >> >> I am on Kubuntu 12.10 using PySide 1.2.1. >> I just ran the code on an OSX box with an old PySide >> installation (1.0.9) and the progressbar didn't move there. >> >> I have a few simple apps to write which will involve proper >> use of progressbar to indicate background image processing, >> so I'm sure I will run into it again. >> >> >> Cheers, >> frank >> >> >> >> On 12/12/13 09:56, Sean Fisk wrote: >>> Janwillem, >>> >>> I'm glad you were able to able to figure out the problem. >>> Sorry for my red herrings! >>> >>> Frank, >>> >>> I thought about it, and I have no idea why the progress bar >>> works fine for you and not for me. It hangs for me, which is >>> exactly what I expected to happen. Maybe some platform >>> difference? I'm on Mac OS 10.6 with PySide 1.2.1. >>> >>> >>> -- >>> Sean Fisk >>> >>> >>> On Wed, Dec 11, 2013 at 9:16 AM, Janwillem van Dijk >>> > wrote: >>> >>> The solution Frank proposed yesterday works (after I >>> found out that you can get the output using >>> selectedFiles()[0]). >>> No problems with the progressbar. >>> The actual processing can take a bit long because the >>> exif's of digital camera shots are analysed (GExiv2 for >>> photos and exiftool for movies ) and than copied to >>> folders as >>> /camara_make/year/month/imagetype/yyyymmddhhmmss_fname. >>> When copying more than say 50 16MB raw photos the gui >>> becomes blocked. In other apps I indeed solved that with >>> threading but, although not elegant, I decided to live >>> with that for this one. >>> Many thanks for teaching me this extra bit of Python. >>> Cheers, Janwillem >>> >>> >>> On 11/12/13 05:45, Sean Fisk wrote: >>>> >>>> Frank, >>>> >>>> Your example is a good demonstration of |QFileDialog|‘s >>>> signals. However, since the processing runs in the GUI >>>> thread, the progress bar is virtually useless as the >>>> GUI has no time to update it. It starts empty, the >>>> application hangs, and then it is filled when the >>>> processing is done. >>>> >>>> Janwillem, >>>> >>>> As I see it, if you would like a progress bar, you have >>>> three options: >>>> >>>> 1. Call |QCoreApplication.processEvents()| >>>> >>>> during your processing code. This is not always a >>>> great idea, and more of a hack than a solution. But >>>> it usually works. >>>> 2. Split your processing into chunks as in this >>>> example >>>> . >>>> However, the code is a bit convoluted and it still >>>> runs in the GUI thread. The whole page that >>>> contains that example is a great read for >>>> asynchronous programming. >>>> 3. Send your processing to a thread, and dispatch >>>> events from the thread indicating the progress. >>>> >>>> The first two solutions involve running processing code >>>> within the GUI thread. If any step of the processing >>>> takes longer than a second, then it’s probably not a >>>> good idea as the user will see the application hang. >>>> Here is an example implementation of the third solution: >>>> >>>> |#!/usr/bin/env python >>>> >>>> # Example: Asynchronously process a directory of files with a progress bar. >>>> >>>> import sys >>>> import os >>>> import time >>>> >>>> from PySideimport QtCore, QtGui >>>> >>>> class ProcessingThread(QtCore.QThread): >>>> # Fired when each file is processed. >>>> file_processed = QtCore.Signal(int, str) >>>> >>>> def __init__(self, parent=None): >>>> super(ProcessingThread, self).__init__(parent) >>>> self.files = [] >>>> >>>> def run(self): >>>> # Code that's run in the thread. >>>> for i, filenamein enumerate(self.files): >>>> # The actual code for one file goes here. Stubbed out with >>>> # time.sleep() for now. >>>> time.sleep(0.5) >>>> print 'Processed:', filename >>>> # Send update to the GUI thread. >>>> self.file_processed.emit(i +1, filename) >>>> >>>> class MyWidget(QtGui.QWidget): >>>> def __init__(self, parent=None): >>>> super(MyWidget, self).__init__(parent) >>>> >>>> # Setup UI. >>>> self._layout = QtGui.QVBoxLayout(self) >>>> self._button = QtGui.QPushButton('Open files...') >>>> self._progress = QtGui.QProgressBar() >>>> self._filelist = QtGui.QPlainTextEdit() >>>> self._layout.addWidget(self._button) >>>> self._layout.addWidget(self._filelist) >>>> self._layout.addWidget(self._progress) >>>> >>>> # Setup events. >>>> self._button.clicked.connect(self._button_clicked) >>>> >>>> # Create the thread. Note that this doesn't actually _start_ it. >>>> self._thread = ProcessingThread() >>>> self._thread.file_processed.connect(self._file_processed) >>>> >>>> # We need to wait for the thread before exiting. Either use this or >>>> # don't let the user close the window if processing is happening. See >>>> # the next method in this class. >>>> QtCore.QCoreApplication.instance().aboutToQuit.connect( >>>> self._thread.wait) >>>> >>>> # def closeEvent(self, event): >>>> # # This is an alternative to waiting for the threads. Just don't let >>>> # # the user close the window. >>>> # if self._thread.isRunning(): >>>> # QtGui.QMessageBox.critical( >>>> # self, 'Processing', >>>> # 'Cannot exit while processing is happening.') >>>> # event.ignore() >>>> # else: >>>> # event.accept() >>>> >>>> def _button_clicked(self): >>>> # If we are already running the processing, produce an error. >>>> if self._thread.isRunning(): >>>> QtGui.QMessageBox.critical( >>>> self,'Processing', >>>> 'Can only process one directory at a time.') >>>> return >>>> >>>> # Get the directory name from the user. >>>> dir_name = QtGui.QFileDialog.getExistingDirectory( >>>> parent=self, >>>> caption='Choose files...', >>>> dir=os.getcwd()) >>>> >>>> # Activate the main dialog as it will be deactivated for some reason >>>> # after the file dialog closes (at least on my machine). >>>> self.activateWindow() >>>> >>>> # Get the list of files in the directory and prime the progress bar. >>>> files = os.listdir(dir_name) >>>> >>>> # Set values for progress bar. >>>> self._progress.setRange(0, len(files)) >>>> self._progress.setValue(0) >>>> >>>> # Create and start the thread. >>>> self._thread.files = files >>>> self._thread.start() >>>> >>>> def _file_processed(self, num_files_processed, filename): >>>> # Called for each file that is processed. >>>> self._filelist.appendPlainText(filename) >>>> self._progress.setValue(num_files_processed) >>>> >>>> if __name__ =='__main__': >>>> app = QtGui.QApplication(sys.argv) >>>> w = MyWidget() >>>> w.show() >>>> w.raise_() >>>> raise SystemExit(app.exec_())| >>>> >>>> This is all fine, but it might not solve your original >>>> problem of the file dialog not closing. On my Mac, the >>>> file dialog is gone as soon as the call to >>>> |getExistingDirectory()| finishes. However, since I >>>> don’t have a runnable portion of your code, I can’t >>>> really test it. I would recommend attempting to run my >>>> example to see if it exhibits the same problem as your >>>> program. Hope this helps! >>>> >>>> Cheers, >>>> >>>> >>>> >>>> >>>> -- >>>> Sean Fisk >>>> >>>> >>>> On Tue, Dec 10, 2013 at 4:43 PM, Frank Rueter | OHUfx >>>> > wrote: >>>> >>>> Here is an example using signals/slots >>>> >>>> >>>> On 11/12/13 09:56, Janwillem van Dijk wrote: >>>>> >>>>> Here is the snippet: It reads the filenames in a >>>>> folder and determines new names for photo's based >>>>> on the exif info. >>>>> >>>>> I apreciate that threading might be a solution but >>>>> the problem seems too simple for that. Can you >>>>> give an example on how to use the signal concept? >>>>> >>>>> >>>>> self.outFolder = QFileDialog.getExistingDirectory( >>>>> >>>>> caption='Destination folder', dir=self.defOutFolder) >>>>> >>>>> self.outFiles = [] >>>>> >>>>> if self.outFolder: >>>>> >>>>> self.outFolder = self.outFolder.replace('\\', '/') >>>>> >>>>> self.lineEdit_dest.setText(self.outFolder) >>>>> >>>>> self.progressBar.setRange(0, self.numFiles) >>>>> >>>>> for i, fname in enumerate(self.inFiles): >>>>> >>>>> self.progressBar.setValue(i + 1) >>>>> >>>>> newpath, newfname = rename_photo(self.inFolder, fname) >>>>> >>>>> newpath = path.join(self.outFolder, newpath) >>>>> >>>>> self.outFiles.append([fname, newpath, newfname]) >>>>> >>>>> s = fname + ' --> ' + self.outFolder + '\n' >>>>> >>>>> s += path.join(newpath, >>>>> newfname).replace(self.outFolder, '') >>>>> >>>>> self.plainTextEdit_dest.appendPlainText(s) >>>>> >>>>> >>>>> >>>>> On 10/12/13 21:35, Sean Fisk wrote: >>>>>> >>>>>> Hi Janwillem, >>>>>> >>>>>> Are you running the “lengthy part that processes >>>>>> a files list” within the GUI thread? If so, you >>>>>> will probably see your GUI hang while this is >>>>>> happening (you won’t be able to click or do >>>>>> anything). In this case, you should consider >>>>>> running the processing in a different thread >>>>>> using QThread >>>>>> >>>>>> or QThreadPool >>>>>> . >>>>>> >>>>>> Can you post the relevant part of the code? >>>>>> >>>>>> Thanks, >>>>>> >>>>>> >>>>>> >>>>>> -- >>>>>> Sean Fisk >>>>>> >>>>>> >>>>>> On Tue, Dec 10, 2013 at 3:17 PM, Janwillem van >>>>>> Dijk >>>>> > wrote: >>>>>> >>>>>> Hi, I have a PySide script that uses >>>>>> QFileDialog.getExistingDirectory(). After >>>>>> clicking the Open button the script proceeds >>>>>> with a lengthy part that processes a files >>>>>> list and writes to a QPlainTextEdit. >>>>>> Unfortunately the QFileDialog widget does >>>>>> only disappear after this processing is >>>>>> finished, hiding the QPlainTextEdit. >>>>>> >>>>>> How can I make that the QFileDialog widget is >>>>>> gone before the processing starts? >>>>>> >>>>>> Cheers, Janwillem >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> _______________________________________________ >>>>>> PySide mailing list >>>>>> PySide at qt-project.org >>>>>> >>>>>> http://lists.qt-project.org/mailman/listinfo/pyside >>>>>> >>>>>> >>>>> >>>> >>>> >>> >>> >> >> > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jwevandijk at xs4all.nl Thu Dec 12 10:50:08 2013 From: jwevandijk at xs4all.nl (Janwillem van Dijk) Date: Thu, 12 Dec 2013 10:50:08 +0100 Subject: [PySide] wait for QFileDialog to close In-Reply-To: References: <52A776CA.60704@xs4all.nl> <52A78016.4020008@xs4all.nl> <52A78AED.3070505@ohufx.com> <52A873BB.6040507@xs4all.nl> <52A8DD15.6040703@ohufx.com> <52A8F254.5020005@ohufx.com> Message-ID: <52A986D0.9030008@xs4all.nl> On 12/12/2013 01:02 AM, Matthew Woehlke wrote: > On 2013-12-11 18:37, Sean Fisk wrote: >> I just tried it on CentOS with PySide 1.2.1. The progress bar does indeed >> work. However, I do see some visual glitches: the layout doesn’t readjust >> if the window is resized; the button sometimes disappears halfway or fully; >> the button can’t be clicked. > This sounds like your environment is coincidentally performing some > update operations synchronously that usually are deferred. This probably > explains why you see different behavior depending on the platform. I've > seen similar artifacts before, e.g. code in projects I work on (not > written by me :P) that shows a 'please wait' dialog before going off and > blocking the GUI thread for some time that "work" (i.e. show up) on some > machines and not on others. > > There are probably a number of factors affecting this; OS is an obvious > one, but widget style could also come into play and I wouldn't be > surprised if even system load can have an effect. IOW, I wouldn't get > too hung up on why it sometimes works, and just write it up as being > unreliable (i.e. something to avoid or work around). > > p.s. You really should never, ever block the GUI thread for more than > ~250ms ;-). Threads (or QtConcurrent) are good for "slow" tasks, or else > make sure you are allowing the event loop to run (i.e. processEvents) > every now and then. > Thanks for this tip: Missed the processEvents possibility which feels rather stupid becaus used something equivalent for years in Pascal (Delphi). I inserted processEvents for every 10th file and the gui stays alive all the time. From nicolas.saubat at imag.fr Thu Dec 12 16:56:47 2013 From: nicolas.saubat at imag.fr (Nicolas SAUBAT) Date: Thu, 12 Dec 2013 16:56:47 +0100 Subject: [PySide] PySide 1.2.1 API Docs In-Reply-To: References: <52A5E8CC.2050200@imag.fr> Message-ID: <52A9DCBF.3070201@imag.fr> An HTML attachment was scrubbed... URL: From nicolas.saubat at imag.fr Thu Dec 12 17:09:33 2013 From: nicolas.saubat at imag.fr (Nicolas SAUBAT) Date: Thu, 12 Dec 2013 17:09:33 +0100 Subject: [PySide] Binding C++/VTK code using Shiboken Message-ID: <52A9DFBD.6030501@imag.fr> Hi PySide users, I'm trying to bind to Python a C++ framework, called CamiTK (http://camitk.imag.fr) which is based on Qt and VTK (http://www.vtk.org/). For binding Qt C++ classes, no problem, we can tell Shiboken how to use Qt in Python, thanks to the provided typesystem.xml files. But I was wondering, how we can do the same stuff using VTK ? I know VTK is already available in Python, thus, to my mind I would need to tell Shiboken, what are the correspondance from the VTK C++ classes to the VTK Python classes, using Shiboken's rules in my input typesystem.xml ? If anyone has been working on a similar problem, please let me know ! Thanks, Nicolas. -- Nicolas SAUBAT Ingénieur Recherche et Développement Equipe GMCAO - Laboratoire TIMC-IMAG Pavillon Taillefer Allée des Alpes - Domaine de la Merci 38706 La Tronche Tel : (33)04 56 52 00 10 From matthew.woehlke at kitware.com Thu Dec 12 18:07:47 2013 From: matthew.woehlke at kitware.com (Matthew Woehlke) Date: Thu, 12 Dec 2013 12:07:47 -0500 Subject: [PySide] Binding C++/VTK code using Shiboken In-Reply-To: <52A9DFBD.6030501@imag.fr> References: <52A9DFBD.6030501@imag.fr> Message-ID: On 2013-12-12 11:09, Nicolas SAUBAT wrote: > I'm trying to bind to Python a C++ framework, called CamiTK > (http://camitk.imag.fr) which is based on Qt and VTK (http://www.vtk.org/). > For binding Qt C++ classes, no problem, we can tell Shiboken how to use > Qt in Python, thanks to the provided typesystem.xml files. > But I was wondering, how we can do the same stuff using VTK ? Well. That's a good question. If you just want to generate bindings for VTK-based objects, VTK has its own wrapping system that will allow you to do that. (IME it's rather limited compared to Shiboken; no support for enums, STL containers, etc.) However, getting the two to talk to each other is likely to be an issue. What you would ultimately need to do, I think, is to be able to teach Shiboken how to get a vtkObject* from a PyObject. As far as the Shiboken architecture, I think you should be able to write custom converters for this. The problem comes with how VTK implements its conversions, which depends on having a pointer to the call arguments, which is not available in Shiboken. As such, I'm not sure that (at the C++ level) it is possible to get the vtkObject* from *just* a PyObject. TBH, I have the same problem and haven't solved it, except that I decided the best thing to do would be to rewrite VTK's wrapping to just use Shiboken and be done with it ;-). If you find a solution, please let me know. (If you can throw $$ at making VTK use Shiboken, please also let me know ;-).) Note that it's probably impossible to wrap a VTK-derived object with Shiboken in any useful way. -- Matthew From nicolas.saubat at imag.fr Fri Dec 13 18:18:44 2013 From: nicolas.saubat at imag.fr (Nicolas SAUBAT) Date: Fri, 13 Dec 2013 18:18:44 +0100 Subject: [PySide] Binding C++/VTK code using Shiboken In-Reply-To: References: <52A9DFBD.6030501@imag.fr> Message-ID: <52AB4174.4000306@imag.fr> Hi Matthew, Thanks a lot for your answer ! So if I understand correctly (as I'm still a beginner in the Python binding world / Shiboken). If I have a C++ class based on both Qt and VTK (like this one : http://camitk.imag.fr/apidocumentation/3.2/classcamitk_1_1RendererWidget.html), I would be able to expose the VTK part using VTK's Python binder OR Qt part using Shiboken, but not both (or I send $$ to VTK to convert them to Shiboken ;-) And then the solution seems to be to still use Shiboken, and inject code in the wrapped classes (containing CPython code) in order to tell it how to convert the Python object (PyObject) into a VTKObject when necessary. Which seems difficult, from the C++ side, regarding how VTK handles its VTKObjects. Please let me know if I've misunderstood some points ! And, by the way, would this problem still occur if we decide not to expose to Python the VTK part ? I mean, we still consider C++ classes based on both Qt and VTK, but only describe in the typesystem.xml files for Shiboken, the C++ and Qt objects we want to expose (thus no rules for VTK objects). This way, the CPython extension generated would still be able to run the VTK methods trought the C++ library, but forbid to directly handle the VTK objects from the Python world (or crashes). But I don't know if it would be possible to render the 3D of VTK in some Qt widget ... Feel free to react, as I said I'm not an expert, any advice is welcome (except sending too much $$ to kitware ;-) ) Thanks, Nicolas. On 12/12/2013 06:07 PM, Matthew Woehlke wrote: > On 2013-12-12 11:09, Nicolas SAUBAT wrote: >> I'm trying to bind to Python a C++ framework, called CamiTK >> (http://camitk.imag.fr) which is based on Qt and VTK (http://www.vtk.org/). >> For binding Qt C++ classes, no problem, we can tell Shiboken how to use >> Qt in Python, thanks to the provided typesystem.xml files. >> But I was wondering, how we can do the same stuff using VTK ? > Well. That's a good question. > > If you just want to generate bindings for VTK-based objects, VTK has its > own wrapping system that will allow you to do that. (IME it's rather > limited compared to Shiboken; no support for enums, STL containers, > etc.) However, getting the two to talk to each other is likely to be an > issue. > > What you would ultimately need to do, I think, is to be able to teach > Shiboken how to get a vtkObject* from a PyObject. As far as the Shiboken > architecture, I think you should be able to write custom converters for > this. > > The problem comes with how VTK implements its conversions, which depends > on having a pointer to the call arguments, which is not available in > Shiboken. As such, I'm not sure that (at the C++ level) it is possible > to get the vtkObject* from *just* a PyObject. > > TBH, I have the same problem and haven't solved it, except that I > decided the best thing to do would be to rewrite VTK's wrapping to just > use Shiboken and be done with it ;-). If you find a solution, please let > me know. (If you can throw $$ at making VTK use Shiboken, please also > let me know ;-).) > > Note that it's probably impossible to wrap a VTK-derived object with > Shiboken in any useful way. > -- Nicolas SAUBAT Ingénieur Recherche et Développement Equipe GMCAO - Laboratoire TIMC-IMAG Pavillon Taillefer Allée des Alpes - Domaine de la Merci 38706 La Tronche Tel : (33)04 56 52 00 10 From matthew.woehlke at kitware.com Fri Dec 13 18:43:13 2013 From: matthew.woehlke at kitware.com (Matthew Woehlke) Date: Fri, 13 Dec 2013 12:43:13 -0500 Subject: [PySide] Binding C++/VTK code using Shiboken In-Reply-To: <52AB4174.4000306@imag.fr> References: <52A9DFBD.6030501@imag.fr> <52AB4174.4000306@imag.fr> Message-ID: On 2013-12-13 12:18, Nicolas SAUBAT wrote: > If I have a C++ class based on both Qt and VTK (like this one : > http://camitk.imag.fr/apidocumentation/3.2/classcamitk_1_1RendererWidget.html), > I would be able to expose the VTK part using VTK's Python binder OR Qt > part using Shiboken, but not both. *AFAIK* this is correct. At least, I know that I've run into the same problem and didn't come up with a solution. > And then the solution seems to be to still use Shiboken, > and inject code in the wrapped classes (containing CPython code) in > order to tell it how to convert the Python object (PyObject) into a > VTKObject when necessary. Which seems difficult, from the C++ side, > regarding how VTK handles its VTKObjects. > Please let me know if I've misunderstood some points ! No, that sounds about right. That said, maybe someone that knows VTK better would have an idea. Have you asked on the VTK list? > And, by the way, would this problem still occur if we decide not to > expose to Python the VTK part ? You can wrap many things in Shiboken. If what you wrap uses Qt classes (and you are using PySide), then you will be able to wrangle those types between C++ and Python (which is really a glorified way of saying you can wrap a method that either takes or returns a Qt type). Where you'll run into trouble (using Shiboken to do the wrapping) is methods that take or return VTK object types. (POD's are not a problem in either case, of course.) Basically, if the API only wraps types that are themselves wrapped by Shiboken, you'll be fine. (Note however that you'll lose base class methods if your base class is not shiboken wrapped.) You could, conceivably, write your own external shiboken-based Python bindings for VTK :-). (After all, PySide is separate from / 'on top of' Qt; no need to be tightly integrated into the VTK repo / build system.) Similarly if you use VTK to do the wrapping, VTK types will be okay but Qt types will be a problem. (Also VTK's binding system has other limitations, e.g. no STL classes, very poor support for enums...) > This way, the CPython extension generated would still be able to run the > VTK methods trought the C++ library, but forbid to directly handle the > VTK objects from the Python world (or crashes). More likely Python just won't "see" methods that deal with VTK objects. > But I don't know if it would be possible to render the 3D of VTK in some > Qt widget ... Hmm... I don't think QVTKWidget is a vtkObject(?); you could write your own wrapping for that and only that with Shiboken that would at least let you create the widget from Python. Assuming you even need to do that. -- Matthew From twangist at yahoo.com Sat Dec 14 19:20:14 2013 From: twangist at yahoo.com (Brian O'Neill) Date: Sat, 14 Dec 2013 13:20:14 -0500 Subject: [PySide] PySide 1.2.1 binary for Mac OS X and Py3.3 In-Reply-To: References: Message-ID: It would be nice if there were such a thing on http://qt-project.org/wiki/PySide_Binaries_MacOSX The Windows page has had one for a while. Surely someone has built a binary -- yes? On Dec 14, 2013, at 6:00 AM, pyside-request at qt-project.org wrote: > Send PySide mailing list submissions to > pyside at qt-project.org > > To subscribe or unsubscribe via the World Wide Web, visit > http://lists.qt-project.org/mailman/listinfo/pyside > or, via email, send a message with subject or body 'help' to > pyside-request at qt-project.org > > You can reach the person managing the list at > pyside-owner at qt-project.org > > When replying, please edit your Subject line so it is more specific > than "Re: Contents of PySide digest..." > Today's Topics: > > 1. Re: Binding C++/VTK code using Shiboken (Nicolas SAUBAT) > 2. Re: Binding C++/VTK code using Shiboken (Matthew Woehlke) > > From: Nicolas SAUBAT > Subject: Re: [PySide] Binding C++/VTK code using Shiboken > Date: December 13, 2013 12:18:44 PM EST > To: pyside at qt-project.org > > > Hi Matthew, > > Thanks a lot for your answer ! > > So if I understand correctly (as I'm still a beginner in the Python binding world / Shiboken). > If I have a C++ class based on both Qt and VTK (like this one : http://camitk.imag.fr/apidocumentation/3.2/classcamitk_1_1RendererWidget.html), I would be able to expose the VTK part using VTK's Python binder OR Qt part using Shiboken, but not both (or I send $$ to VTK to convert them to Shiboken ;-) And then the solution seems to be to still use Shiboken, and inject code in the wrapped classes (containing CPython code) in order to tell it how to convert the Python object (PyObject) into a VTKObject when necessary. Which seems difficult, from the C++ side, regarding how VTK handles its VTKObjects. > Please let me know if I've misunderstood some points ! > > And, by the way, would this problem still occur if we decide not to expose to Python the VTK part ? > I mean, we still consider C++ classes based on both Qt and VTK, but only describe in the typesystem.xml files for Shiboken, the C++ and Qt objects we want to expose (thus no rules for VTK objects). > This way, the CPython extension generated would still be able to run the VTK methods trought the C++ library, but forbid to directly handle the VTK objects from the Python world (or crashes). > But I don't know if it would be possible to render the 3D of VTK in some Qt widget ... > > Feel free to react, as I said I'm not an expert, any advice is welcome (except sending too much $$ to kitware ;-) ) > > Thanks, > Nicolas. > > > On 12/12/2013 06:07 PM, Matthew Woehlke wrote: >> On 2013-12-12 11:09, Nicolas SAUBAT wrote: >>> I'm trying to bind to Python a C++ framework, called CamiTK >>> (http://camitk.imag.fr) which is based on Qt and VTK (http://www.vtk.org/). >>> For binding Qt C++ classes, no problem, we can tell Shiboken how to use >>> Qt in Python, thanks to the provided typesystem.xml files. >>> But I was wondering, how we can do the same stuff using VTK ? >> Well. That's a good question. >> >> If you just want to generate bindings for VTK-based objects, VTK has its >> own wrapping system that will allow you to do that. (IME it's rather >> limited compared to Shiboken; no support for enums, STL containers, >> etc.) However, getting the two to talk to each other is likely to be an >> issue. >> >> What you would ultimately need to do, I think, is to be able to teach >> Shiboken how to get a vtkObject* from a PyObject. As far as the Shiboken >> architecture, I think you should be able to write custom converters for >> this. >> >> The problem comes with how VTK implements its conversions, which depends >> on having a pointer to the call arguments, which is not available in >> Shiboken. As such, I'm not sure that (at the C++ level) it is possible >> to get the vtkObject* from *just* a PyObject. >> >> TBH, I have the same problem and haven't solved it, except that I >> decided the best thing to do would be to rewrite VTK's wrapping to just >> use Shiboken and be done with it ;-). If you find a solution, please let >> me know. (If you can throw $$ at making VTK use Shiboken, please also >> let me know ;-).) >> >> Note that it's probably impossible to wrap a VTK-derived object with >> Shiboken in any useful way. >> > > -- > Nicolas SAUBAT > Ingénieur Recherche et Développement > Equipe GMCAO - Laboratoire TIMC-IMAG > Pavillon Taillefer > Allée des Alpes - Domaine de la Merci > 38706 La Tronche > Tel : (33)04 56 52 00 10 > > > > > > From: Matthew Woehlke > Subject: Re: [PySide] Binding C++/VTK code using Shiboken > Date: December 13, 2013 12:43:13 PM EST > To: pyside at qt-project.org > > > On 2013-12-13 12:18, Nicolas SAUBAT wrote: >> If I have a C++ class based on both Qt and VTK (like this one : >> http://camitk.imag.fr/apidocumentation/3.2/classcamitk_1_1RendererWidget.html), >> I would be able to expose the VTK part using VTK's Python binder OR Qt >> part using Shiboken, but not both. > > *AFAIK* this is correct. At least, I know that I've run into the same problem and didn't come up with a solution. > >> And then the solution seems to be to still use Shiboken, >> and inject code in the wrapped classes (containing CPython code) in >> order to tell it how to convert the Python object (PyObject) into a >> VTKObject when necessary. Which seems difficult, from the C++ side, >> regarding how VTK handles its VTKObjects. >> Please let me know if I've misunderstood some points ! > > No, that sounds about right. > > That said, maybe someone that knows VTK better would have an idea. Have you asked on the VTK list? > >> And, by the way, would this problem still occur if we decide not to >> expose to Python the VTK part ? > > You can wrap many things in Shiboken. If what you wrap uses Qt classes (and you are using PySide), then you will be able to wrangle those types between C++ and Python (which is really a glorified way of saying you can wrap a method that either takes or returns a Qt type). Where you'll run into trouble (using Shiboken to do the wrapping) is methods that take or return VTK object types. (POD's are not a problem in either case, of course.) Basically, if the API only wraps types that are themselves wrapped by Shiboken, you'll be fine. (Note however that you'll lose base class methods if your base class is not shiboken wrapped.) > > You could, conceivably, write your own external shiboken-based Python bindings for VTK :-). (After all, PySide is separate from / 'on top of' Qt; no need to be tightly integrated into the VTK repo / build system.) > > Similarly if you use VTK to do the wrapping, VTK types will be okay but Qt types will be a problem. (Also VTK's binding system has other limitations, e.g. no STL classes, very poor support for enums...) > >> This way, the CPython extension generated would still be able to run the >> VTK methods trought the C++ library, but forbid to directly handle the >> VTK objects from the Python world (or crashes). > > More likely Python just won't "see" methods that deal with VTK objects. > >> But I don't know if it would be possible to render the 3D of VTK in some >> Qt widget ... > > Hmm... I don't think QVTKWidget is a vtkObject(?); you could write your own wrapping for that and only that with Shiboken that would at least let you create the widget from Python. Assuming you even need to do that. > > -- > Matthew > > > > > _______________________________________________ > PySide mailing list > PySide at qt-project.org > http://lists.qt-project.org/mailman/listinfo/pyside -------------- next part -------------- An HTML attachment was scrubbed... URL: From mail at markus-ullmann.de Mon Dec 16 01:18:15 2013 From: mail at markus-ullmann.de (Markus Ullmann) Date: Mon, 16 Dec 2013 00:18:15 +0000 Subject: [PySide] PySide 1.2.1 Mac beta releases Message-ID: Hello everyone, finally after getting my dev environment up and running again, combined with a dev id for signed installers, I have put up a package for beta use. The packages have been built using original Qt 4.8.5 from Website and Apple Python 2.7.5 on Mavericks. Currently there are a small numbers on test suite failures: 99% tests passed, 3 tests failed out of 409 The following tests FAILED: 21 - signals_disconnect_test (Failed) 308 - QtGui_qstandarditemmodel_test (Failed) 348 - QtWebKit_shouldInterruptjavascript_test (Timeout) Download Link: http://pyside.markus-ullmann.de/pyside-1.2.1-qt4.8.5-py27apple-developer-signed.pkg Package Content: http://pyside.markus-ullmann.de/pyside-1.2.1-qt4.8.5-py27apple.pkg.bom.txt I’m interested in hearing your feedback. Best Regards Markus -------------- next part -------------- An HTML attachment was scrubbed... URL: From frank at ohufx.com Mon Dec 16 08:01:12 2013 From: frank at ohufx.com (Frank Rueter | OHUfx) Date: Mon, 16 Dec 2013 20:01:12 +1300 Subject: [PySide] most basic QThread problem Message-ID: <52AEA538.7060304@ohufx.com> Hi all, I am playing with simple QThread object and am getting the ol' "QThread: Destroyed while thread is still running" error. I have searched the web quite a bit now and keep running into examples that do exactly what I am doing, except it seems to work for others. Can somebody tell me where I'm going wrong with this bare bones examples please? Cheers, frank from PySide import QtCore import time class MyThread(QtCore.QThread): def __init__(self, parent=None): super(MyThread, self).__init__(parent) def run(self): for i in xrange(10): print i time.sleep(1) class MainApp(QtCore.QObject): def __init__(self, parent=None): super(MainApp, self).__init__(parent) self.thread = MyThread(self) def doIt(self): self.thread.start() if __name__ == '__main__': a = MainApp() a.doIt() From sebastian at risefx.com Mon Dec 16 09:02:42 2013 From: sebastian at risefx.com (Sebastian Elsner) Date: Mon, 16 Dec 2013 09:02:42 +0100 Subject: [PySide] most basic QThread problem In-Reply-To: <52AEA538.7060304@ohufx.com> References: <52AEA538.7060304@ohufx.com> Message-ID: <52AEB3A2.3000408@risefx.com> Hi, according to the latest 4.8.4 documentation the subclass approach is wrong: http://qt-project.org/doc/qt-4.8/qthread.html For an in-depth explanation see: http://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/ It's all C++ but the second link is very readable easy to understand. Cheers Sebastian Am 16.12.2013 08:01, schrieb Frank Rueter | OHUfx: > Hi all, > > > I am playing with simple QThread object and am getting the ol' "QThread: > Destroyed while thread is still running" error. > > I have searched the web quite a bit now and keep running into examples > that do exactly what I am doing, except it seems to work for others. > Can somebody tell me where I'm going wrong with this bare bones examples > please? > > Cheers, > frank > > from PySide import QtCore > import time > > class MyThread(QtCore.QThread): > > def __init__(self, parent=None): > super(MyThread, self).__init__(parent) > > def run(self): > for i in xrange(10): > print i > time.sleep(1) > > class MainApp(QtCore.QObject): > > def __init__(self, parent=None): > super(MainApp, self).__init__(parent) > self.thread = MyThread(self) > > def doIt(self): > self.thread.start() > > if __name__ == '__main__': > a = MainApp() > a.doIt() > > _______________________________________________ > PySide mailing list > PySide at qt-project.org > http://lists.qt-project.org/mailman/listinfo/pyside From frank at ohufx.com Mon Dec 16 09:55:03 2013 From: frank at ohufx.com (Frank Rueter | OHUfx) Date: Mon, 16 Dec 2013 21:55:03 +1300 Subject: [PySide] most basic QThread problem In-Reply-To: <52AEB3A2.3000408@risefx.com> References: <52AEA538.7060304@ohufx.com> <52AEB3A2.3000408@risefx.com> Message-ID: <52AEBFE7.6070202@ohufx.com> Thanks Sebastian! I did see all those comments against sub classing, but at the same time so many examples (including in the docs) that went with it. I will read through the article tomorrow (it's getting late here). Cheers, frank On 16/12/13 21:02, Sebastian Elsner wrote: > Hi, > > according to the latest 4.8.4 documentation the subclass approach is > wrong: http://qt-project.org/doc/qt-4.8/qthread.html > For an in-depth explanation see: > http://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/ > It's all C++ but the second link is very readable easy to understand. > > > Cheers > > > Sebastian > > > Am 16.12.2013 08:01, schrieb Frank Rueter | OHUfx: >> Hi all, >> >> >> I am playing with simple QThread object and am getting the ol' "QThread: >> Destroyed while thread is still running" error. >> >> I have searched the web quite a bit now and keep running into examples >> that do exactly what I am doing, except it seems to work for others. >> Can somebody tell me where I'm going wrong with this bare bones examples >> please? >> >> Cheers, >> frank >> >> from PySide import QtCore >> import time >> >> class MyThread(QtCore.QThread): >> >> def __init__(self, parent=None): >> super(MyThread, self).__init__(parent) >> >> def run(self): >> for i in xrange(10): >> print i >> time.sleep(1) >> >> class MainApp(QtCore.QObject): >> >> def __init__(self, parent=None): >> super(MainApp, self).__init__(parent) >> self.thread = MyThread(self) >> >> def doIt(self): >> self.thread.start() >> >> if __name__ == '__main__': >> a = MainApp() >> a.doIt() >> >> _______________________________________________ >> PySide mailing list >> PySide at qt-project.org >> http://lists.qt-project.org/mailman/listinfo/pyside > _______________________________________________ > PySide mailing list > PySide at qt-project.org > http://lists.qt-project.org/mailman/listinfo/pyside From sebastian at risefx.com Mon Dec 16 10:13:00 2013 From: sebastian at risefx.com (Sebastian Elsner) Date: Mon, 16 Dec 2013 10:13:00 +0100 Subject: [PySide] most basic QThread problem In-Reply-To: <52AEBFE7.6070202@ohufx.com> References: <52AEA538.7060304@ohufx.com> <52AEB3A2.3000408@risefx.com> <52AEBFE7.6070202@ohufx.com> Message-ID: <52AEC41C.1070402@risefx.com> The original author of the QThread class at Nokia wrote an article on this a long time back: http://blog.qt.digia.com/blog/2010/06/17/youre-doing-it-wrong/ There has been some discussion, but the official way (by the docs) is not subclassing now. http://qt-project.org/doc/note_revisions/5/33/view http://woboq.com/blog/qthread-you-were-not-doing-so-wrong.html On 12/16/2013 09:55 AM, Frank Rueter | OHUfx wrote: > Thanks Sebastian! > I did see all those comments against sub classing, but at the same time > so many examples (including in the docs) that went with it. > I will read through the article tomorrow (it's getting late here). > > Cheers, > frank > > > On 16/12/13 21:02, Sebastian Elsner wrote: >> Hi, >> >> according to the latest 4.8.4 documentation the subclass approach is >> wrong: http://qt-project.org/doc/qt-4.8/qthread.html >> For an in-depth explanation see: >> http://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/ >> It's all C++ but the second link is very readable easy to understand. >> >> >> Cheers >> >> >> Sebastian >> >> >> Am 16.12.2013 08:01, schrieb Frank Rueter | OHUfx: >>> Hi all, >>> >>> >>> I am playing with simple QThread object and am getting the ol' "QThread: >>> Destroyed while thread is still running" error. >>> >>> I have searched the web quite a bit now and keep running into examples >>> that do exactly what I am doing, except it seems to work for others. >>> Can somebody tell me where I'm going wrong with this bare bones examples >>> please? >>> >>> Cheers, >>> frank >>> >>> from PySide import QtCore >>> import time >>> >>> class MyThread(QtCore.QThread): >>> >>> def __init__(self, parent=None): >>> super(MyThread, self).__init__(parent) >>> >>> def run(self): >>> for i in xrange(10): >>> print i >>> time.sleep(1) >>> >>> class MainApp(QtCore.QObject): >>> >>> def __init__(self, parent=None): >>> super(MainApp, self).__init__(parent) >>> self.thread = MyThread(self) >>> >>> def doIt(self): >>> self.thread.start() >>> >>> if __name__ == '__main__': >>> a = MainApp() >>> a.doIt() >>> >>> _______________________________________________ >>> PySide mailing list >>> PySide at qt-project.org >>> http://lists.qt-project.org/mailman/listinfo/pyside >> _______________________________________________ >> PySide mailing list >> PySide at qt-project.org >> http://lists.qt-project.org/mailman/listinfo/pyside > _______________________________________________ > PySide mailing list > PySide at qt-project.org > http://lists.qt-project.org/mailman/listinfo/pyside -- check out www.pointcloud9.com Sebastian Elsner - Pipeline Technical Director - RISE t: +49 30 20180300 florian at risefx.com f: +49 30 61651074 www.risefx.com RISE FX GmbH Schlesische Strasse 28, Aufgang B, 10997 Berlin c/o action concept, An der Hasenkaule 1-7, 50354 Hürth Geschaeftsfuehrer: Sven Pannicke, Robert Pinnow Handelsregister Berlin HRB 106667 B From dmccombs at dyn.com Mon Dec 16 14:54:35 2013 From: dmccombs at dyn.com (Dan McCombs) Date: Mon, 16 Dec 2013 08:54:35 -0500 Subject: [PySide] most basic QThread problem In-Reply-To: <52AEA538.7060304@ohufx.com> References: <52AEA538.7060304@ohufx.com> Message-ID: Hey Frank, I think the real reason you're getting that message isn't the subclassing piece, but that your program is exiting before the thread has finished. There's nothing in your application to keep it running after running the doIt method, so it exits, and destroys the thread. Normally you would have a QApplication instance and be calling the exec_ method on that after doIt to start your application's event loop and keep it running, until it was quit via some user interaction. -Dan [image: Dyn logo, Dyn.com] [image: Dyn facebook account] [image: Dyn LinkedIn account] Dan McCombs / Senior Software Engineer 603 296 1568 @danmccombs On Mon, Dec 16, 2013 at 2:01 AM, Frank Rueter | OHUfx wrote: > Hi all, > > > I am playing with simple QThread object and am getting the ol' "QThread: > Destroyed while thread is still running" error. > > I have searched the web quite a bit now and keep running into examples > that do exactly what I am doing, except it seems to work for others. > Can somebody tell me where I'm going wrong with this bare bones examples > please? > > Cheers, > frank > > from PySide import QtCore > import time > > class MyThread(QtCore.QThread): > > def __init__(self, parent=None): > super(MyThread, self).__init__(parent) > > def run(self): > for i in xrange(10): > print i > time.sleep(1) > > class MainApp(QtCore.QObject): > > def __init__(self, parent=None): > super(MainApp, self).__init__(parent) > self.thread = MyThread(self) > > def doIt(self): > self.thread.start() > > if __name__ == '__main__': > a = MainApp() > a.doIt() > > _______________________________________________ > PySide mailing list > PySide at qt-project.org > http://lists.qt-project.org/mailman/listinfo/pyside > -------------- next part -------------- An HTML attachment was scrubbed... URL: From matthew.woehlke at kitware.com Mon Dec 16 18:36:48 2013 From: matthew.woehlke at kitware.com (Matthew Woehlke) Date: Mon, 16 Dec 2013 12:36:48 -0500 Subject: [PySide] most basic QThread problem In-Reply-To: <52AEA538.7060304@ohufx.com> References: <52AEA538.7060304@ohufx.com> Message-ID: On 2013-12-16 02:01, Frank Rueter | OHUfx wrote: > I am playing with simple QThread object and am getting the ol' "QThread: > Destroyed while thread is still running" error. I would encourage you to always call wait() on your thread before it is destroyed. -- Matthew From frank at ohufx.com Mon Dec 16 20:28:22 2013 From: frank at ohufx.com (Frank Rueter | OHUfx) Date: Tue, 17 Dec 2013 08:28:22 +1300 Subject: [PySide] most basic QThread problem In-Reply-To: References: <52AEA538.7060304@ohufx.com> Message-ID: <52AF5456.4080100@ohufx.com> ah, that makes perfect sense, thank you! On 17/12/13 02:54, Dan McCombs wrote: > Hey Frank, > > I think the real reason you're getting that message isn't the > subclassing piece, but that your program is exiting before the thread > has finished. There's nothing in your application to keep it running > after running the doIt method, so it exits, and destroys the thread. > Normally you would have a QApplication instance and be calling the > exec_ method on that after doIt to start your application's event loop > and keep it running, until it was quit via some user interaction. > > -Dan > > Dyn logo, Dyn.com Dyn > facebook account Dyn LinkedIn account > > > Dan McCombs / Senior Software Engineer > 603 296 1568 @danmccombs > > > > On Mon, Dec 16, 2013 at 2:01 AM, Frank Rueter | OHUfx > wrote: > > Hi all, > > > I am playing with simple QThread object and am getting the ol' > "QThread: > Destroyed while thread is still running" error. > > I have searched the web quite a bit now and keep running into examples > that do exactly what I am doing, except it seems to work for others. > Can somebody tell me where I'm going wrong with this bare bones > examples > please? > > Cheers, > frank > > from PySide import QtCore > import time > > class MyThread(QtCore.QThread): > > def __init__(self, parent=None): > super(MyThread, self).__init__(parent) > > def run(self): > for i in xrange(10): > print i > time.sleep(1) > > class MainApp(QtCore.QObject): > > def __init__(self, parent=None): > super(MainApp, self).__init__(parent) > self.thread = MyThread(self) > > def doIt(self): > self.thread.start() > > if __name__ == '__main__': > a = MainApp() > a.doIt() > > _______________________________________________ > PySide mailing list > PySide at qt-project.org > http://lists.qt-project.org/mailman/listinfo/pyside > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From frank at ohufx.com Mon Dec 16 20:32:39 2013 From: frank at ohufx.com (Frank Rueter | OHUfx) Date: Tue, 17 Dec 2013 08:32:39 +1300 Subject: [PySide] most basic QThread problem In-Reply-To: References: <52AEA538.7060304@ohufx.com> Message-ID: <52AF5557.7070903@ohufx.com> Thanks Mat, will wait() block concurrent threads? In my case my app will receive an arbitrary amount of tasks and I need to figure out how many of those tasks I want to run at the same time. At the moment I am using a simple threading.Thread ad threading.BoundedSemaphore combo to sensibly limit the amount of concurrent tasks (could be hundreds), and queue outstanding ones. I would however like to switch to QThread as I have a feeling QT's threading its more elegant than python's?! Cheers, frank On 17/12/13 06:36, Matthew Woehlke wrote: > On 2013-12-16 02:01, Frank Rueter | OHUfx wrote: >> I am playing with simple QThread object and am getting the ol' "QThread: >> Destroyed while thread is still running" error. > I would encourage you to always call wait() on your thread before it is > destroyed. > From sean at seanfisk.com Mon Dec 16 20:33:19 2013 From: sean at seanfisk.com (Sean Fisk) Date: Mon, 16 Dec 2013 14:33:19 -0500 Subject: [PySide] most basic QThread problem In-Reply-To: <52AF5456.4080100@ohufx.com> References: <52AEA538.7060304@ohufx.com> <52AF5456.4080100@ohufx.com> Message-ID: Hi Frank, The example that I provided Janwillem in his thread about QFileDialog shows two ways to wait for a thread: one by connect the thread’s wait() slot to QApplication’s aboutToQuit signal, the other by overriding closeEvent() on the main widget. Comments in the code explain the two approaches. Hope this helps, -- Sean Fisk On Mon, Dec 16, 2013 at 2:28 PM, Frank Rueter | OHUfx wrote: > ah, that makes perfect sense, thank you! > > > On 17/12/13 02:54, Dan McCombs wrote: > > Hey Frank, > > I think the real reason you're getting that message isn't the > subclassing piece, but that your program is exiting before the thread has > finished. There's nothing in your application to keep it running after > running the doIt method, so it exits, and destroys the thread. Normally you > would have a QApplication instance and be calling the exec_ method on that > after doIt to start your application's event loop and keep it running, > until it was quit via some user interaction. > > -Dan > > [image: Dyn logo, Dyn.com] > [image: Dyn facebook account] [image: Dyn > LinkedIn account] > > Dan McCombs / Senior Software Engineer > 603 296 1568 @danmccombs > > > On Mon, Dec 16, 2013 at 2:01 AM, Frank Rueter | OHUfx wrote: > >> Hi all, >> >> >> I am playing with simple QThread object and am getting the ol' "QThread: >> Destroyed while thread is still running" error. >> >> I have searched the web quite a bit now and keep running into examples >> that do exactly what I am doing, except it seems to work for others. >> Can somebody tell me where I'm going wrong with this bare bones examples >> please? >> >> Cheers, >> frank >> >> from PySide import QtCore >> import time >> >> class MyThread(QtCore.QThread): >> >> def __init__(self, parent=None): >> super(MyThread, self).__init__(parent) >> >> def run(self): >> for i in xrange(10): >> print i >> time.sleep(1) >> >> class MainApp(QtCore.QObject): >> >> def __init__(self, parent=None): >> super(MainApp, self).__init__(parent) >> self.thread = MyThread(self) >> >> def doIt(self): >> self.thread.start() >> >> if __name__ == '__main__': >> a = MainApp() >> a.doIt() >> >> _______________________________________________ >> PySide mailing list >> PySide at qt-project.org >> http://lists.qt-project.org/mailman/listinfo/pyside >> > > > > _______________________________________________ > PySide mailing list > PySide at qt-project.org > http://lists.qt-project.org/mailman/listinfo/pyside > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From sean at seanfisk.com Mon Dec 16 20:39:57 2013 From: sean at seanfisk.com (Sean Fisk) Date: Mon, 16 Dec 2013 14:39:57 -0500 Subject: [PySide] most basic QThread problem In-Reply-To: <52AF5557.7070903@ohufx.com> References: <52AEA538.7060304@ohufx.com> <52AF5557.7070903@ohufx.com> Message-ID: Hi Frank, If you need to run a number of tasks, limit the amount that are running concurrently, and would like to use Qt’s event system, then I think QThreadPoolwith setMaxThreadCount()is your best option. Sincerely, -- Sean Fisk On Mon, Dec 16, 2013 at 2:32 PM, Frank Rueter | OHUfx wrote: > Thanks Mat, > will wait() block concurrent threads? > In my case my app will receive an arbitrary amount of tasks and I need > to figure out how many of those tasks I want to run at the same time. > At the moment I am using a simple threading.Thread ad > threading.BoundedSemaphore combo to sensibly limit the amount of > concurrent tasks (could be hundreds), and queue outstanding ones. > I would however like to switch to QThread as I have a feeling QT's > threading its more elegant than python's?! > > Cheers, > frank > > > > On 17/12/13 06:36, Matthew Woehlke wrote: > > On 2013-12-16 02:01, Frank Rueter | OHUfx wrote: > >> I am playing with simple QThread object and am getting the ol' "QThread: > >> Destroyed while thread is still running" error. > > I would encourage you to always call wait() on your thread before it is > > destroyed. > > > > _______________________________________________ > PySide mailing list > PySide at qt-project.org > http://lists.qt-project.org/mailman/listinfo/pyside > -------------- next part -------------- An HTML attachment was scrubbed... URL: From frank at ohufx.com Mon Dec 16 20:47:59 2013 From: frank at ohufx.com (Frank Rueter | OHUfx) Date: Tue, 17 Dec 2013 08:47:59 +1300 Subject: [PySide] most basic QThread problem In-Reply-To: References: <52AEA538.7060304@ohufx.com> <52AF5456.4080100@ohufx.com> Message-ID: <52AF58EF.10004@ohufx.com> Thanks Sean, makes sense On 17/12/13 08:33, Sean Fisk wrote: > > Hi Frank, > > The example that I provided Janwillem in his thread about QFileDialog > shows two ways to wait for a thread: one by connect the thread’s > |wait()| slot to QApplication’s |aboutToQuit| signal, the other by > overriding |closeEvent()| on the main widget. Comments in the code > explain the two approaches. > > Hope this helps, > > > > -- > Sean Fisk > > > On Mon, Dec 16, 2013 at 2:28 PM, Frank Rueter | OHUfx > wrote: > > ah, that makes perfect sense, thank you! > > > On 17/12/13 02:54, Dan McCombs wrote: >> Hey Frank, >> >> I think the real reason you're getting that message isn't the >> subclassing piece, but that your program is exiting before the >> thread has finished. There's nothing in your application to keep >> it running after running the doIt method, so it exits, and >> destroys the thread. Normally you would have a QApplication >> instance and be calling the exec_ method on that after doIt to >> start your application's event loop and keep it running, until it >> was quit via some user interaction. >> >> -Dan >> >> Dyn logo, Dyn.com Dyn >> facebook account Dyn LinkedIn account >> >> >> Dan McCombs / Senior Software Engineer >> 603 296 1568 @danmccombs >> >> >> >> >> On Mon, Dec 16, 2013 at 2:01 AM, Frank Rueter | OHUfx >> > wrote: >> >> Hi all, >> >> >> I am playing with simple QThread object and am getting the >> ol' "QThread: >> Destroyed while thread is still running" error. >> >> I have searched the web quite a bit now and keep running into >> examples >> that do exactly what I am doing, except it seems to work for >> others. >> Can somebody tell me where I'm going wrong with this bare >> bones examples >> please? >> >> Cheers, >> frank >> >> from PySide import QtCore >> import time >> >> class MyThread(QtCore.QThread): >> >> def __init__(self, parent=None): >> super(MyThread, self).__init__(parent) >> >> def run(self): >> for i in xrange(10): >> print i >> time.sleep(1) >> >> class MainApp(QtCore.QObject): >> >> def __init__(self, parent=None): >> super(MainApp, self).__init__(parent) >> self.thread = MyThread(self) >> >> def doIt(self): >> self.thread.start() >> >> if __name__ == '__main__': >> a = MainApp() >> a.doIt() >> >> _______________________________________________ >> PySide mailing list >> PySide at qt-project.org >> http://lists.qt-project.org/mailman/listinfo/pyside >> >> > > > _______________________________________________ > PySide mailing list > PySide at qt-project.org > http://lists.qt-project.org/mailman/listinfo/pyside > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From matthew.woehlke at kitware.com Mon Dec 16 20:48:07 2013 From: matthew.woehlke at kitware.com (Matthew Woehlke) Date: Mon, 16 Dec 2013 14:48:07 -0500 Subject: [PySide] most basic QThread problem In-Reply-To: <52AF5557.7070903@ohufx.com> References: <52AEA538.7060304@ohufx.com> <52AF5557.7070903@ohufx.com> Message-ID: On 2013-12-16 14:32, Frank Rueter | OHUfx wrote: > will wait() block concurrent threads? wait() blocks the thread from which it is called until the thread on which it is called terminates. Generally you should be calling this when the application is about to exit, or e.g. when you've instructed the thread to exit and it is not expected to hang around much longer (or has already exited). > In my case my app will receive an arbitrary amount of tasks and I need > to figure out how many of those tasks I want to run at the same time. That sounds like a job for QThreadPool and/or QtConcurrent. I would try to avoid actually creating a large number of threads, as they consume system resources, and instead create a work queue and limit the number of threads that ever exist concurrently. (QtConcurrent basically does that for you, automatically. I haven't worked with QThreadPool but I believe it is similar; in fact I believe it is used to implement QtConcurrent.) -- Matthew From frank at ohufx.com Mon Dec 16 20:48:36 2013 From: frank at ohufx.com (Frank Rueter | OHUfx) Date: Tue, 17 Dec 2013 08:48:36 +1300 Subject: [PySide] most basic QThread problem In-Reply-To: References: <52AEA538.7060304@ohufx.com> <52AF5557.7070903@ohufx.com> Message-ID: <52AF5914.8010109@ohufx.com> yes, that's exactly what I am aiming for, just wanted to get the basics right before I confuse myself too much :) cheers, frank On 17/12/13 08:39, Sean Fisk wrote: > > Hi Frank, > > If you need to run a number of tasks, limit the amount that are > running concurrently, and would like to use Qt’s event system, then I > think |QThreadPool| > > with |setMaxThreadCount()| > > is your best option. > > Sincerely, > > > > -- > Sean Fisk > > > On Mon, Dec 16, 2013 at 2:32 PM, Frank Rueter | OHUfx > wrote: > > Thanks Mat, > will wait() block concurrent threads? > In my case my app will receive an arbitrary amount of tasks and I need > to figure out how many of those tasks I want to run at the same time. > At the moment I am using a simple threading.Thread ad > threading.BoundedSemaphore combo to sensibly limit the amount of > concurrent tasks (could be hundreds), and queue outstanding ones. > I would however like to switch to QThread as I have a feeling QT's > threading its more elegant than python's?! > > Cheers, > frank > > > > On 17/12/13 06:36, Matthew Woehlke wrote: > > On 2013-12-16 02:01, Frank Rueter | OHUfx wrote: > >> I am playing with simple QThread object and am getting the ol' > "QThread: > >> Destroyed while thread is still running" error. > > I would encourage you to always call wait() on your thread > before it is > > destroyed. > > > > _______________________________________________ > PySide mailing list > PySide at qt-project.org > http://lists.qt-project.org/mailman/listinfo/pyside > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From frank at ohufx.com Mon Dec 16 21:48:10 2013 From: frank at ohufx.com (Frank Rueter | OHUfx) Date: Tue, 17 Dec 2013 09:48:10 +1300 Subject: [PySide] most basic QThread problem In-Reply-To: References: <52AEA538.7060304@ohufx.com> <52AF5557.7070903@ohufx.com> Message-ID: <52AF670A.8060805@ohufx.com> Thanks Matt, >>create a work queue and limit the number of threads that ever exist concurrently. that is exactly my goal. Cheers, frank On 17/12/13 08:48, Matthew Woehlke wrote: > On 2013-12-16 14:32, Frank Rueter | OHUfx wrote: >> will wait() block concurrent threads? > wait() blocks the thread from which it is called until the thread on > which it is called terminates. Generally you should be calling this when > the application is about to exit, or e.g. when you've instructed the > thread to exit and it is not expected to hang around much longer (or has > already exited). > >> In my case my app will receive an arbitrary amount of tasks and I need >> to figure out how many of those tasks I want to run at the same time. > That sounds like a job for QThreadPool and/or QtConcurrent. I would try > to avoid actually creating a large number of threads, as they consume > system resources, and instead create a work queue and limit the number > of threads that ever exist concurrently. (QtConcurrent basically does > that for you, automatically. I haven't worked with QThreadPool but I > believe it is similar; in fact I believe it is used to implement > QtConcurrent.) > From nicolas.saubat at imag.fr Tue Dec 17 10:19:37 2013 From: nicolas.saubat at imag.fr (Nicolas SAUBAT) Date: Tue, 17 Dec 2013 10:19:37 +0100 Subject: [PySide] Binding C++/VTK code using Shiboken In-Reply-To: References: <52A9DFBD.6030501@imag.fr> <52AB4174.4000306@imag.fr> Message-ID: <52B01729.10604@imag.fr> Thanks again Matthew for this answer, On 12/13/2013 06:43 PM, Matthew Woehlke wrote: > On 2013-12-13 12:18, Nicolas SAUBAT wrote: >> If I have a C++ class based on both Qt and VTK (like this one : >> http://camitk.imag.fr/apidocumentation/3.2/classcamitk_1_1RendererWidget.html), >> I would be able to expose the VTK part using VTK's Python binder OR Qt >> part using Shiboken, but not both. > *AFAIK* this is correct. At least, I know that I've run into the same > problem and didn't come up with a solution. > >> And then the solution seems to be to still use Shiboken, >> and inject code in the wrapped classes (containing CPython code) in >> order to tell it how to convert the Python object (PyObject) into a >> VTKObject when necessary. Which seems difficult, from the C++ side, >> regarding how VTK handles its VTKObjects. >> Please let me know if I've misunderstood some points ! > No, that sounds about right. > > That said, maybe someone that knows VTK better would have an idea. Have > you asked on the VTK list? Not yet, but I will certainly need in the future ! >> And, by the way, would this problem still occur if we decide not to >> expose to Python the VTK part ? > You can wrap many things in Shiboken. If what you wrap uses Qt classes > (and you are using PySide), then you will be able to wrangle those types > between C++ and Python (which is really a glorified way of saying you > can wrap a method that either takes or returns a Qt type). Where you'll > run into trouble (using Shiboken to do the wrapping) is methods that > take or return VTK object types. (POD's are not a problem in either > case, of course.) Basically, if the API only wraps types that are > themselves wrapped by Shiboken, you'll be fine. (Note however that > you'll lose base class methods if your base class is not shiboken wrapped.) > > You could, conceivably, write your own external shiboken-based Python > bindings for VTK :-). (After all, PySide is separate from / 'on top of' > Qt; no need to be tightly integrated into the VTK repo / build system.) Which seems the best things to do. I will go, step by step, on quite that direction (or failed if it's too hard). I've counted 99 vtk classes included in our code (yeah, less than 100, it's psychological :) ). I will, firstly bind our code hiding VTK from Shiboken, and then expose it class by class. Have you already tried binding VTK with Shiboken on your own ? > Similarly if you use VTK to do the wrapping, VTK types will be okay but > Qt types will be a problem. (Also VTK's binding system has other > limitations, e.g. no STL classes, very poor support for enums...) > >> This way, the CPython extension generated would still be able to run the >> VTK methods trought the C++ library, but forbid to directly handle the >> VTK objects from the Python world (or crashes). > More likely Python just won't "see" methods that deal with VTK objects. Yes, that seems logical. > >> But I don't know if it would be possible to render the 3D of VTK in some >> Qt widget ... > Hmm... I don't think QVTKWidget is a vtkObject(?); you could write your > own wrapping for that and only that with Shiboken that would at least > let you create the widget from Python. Assuming you even need to do that. Yes it is used by Qt to render VTK within a widget. My first goal will be to render the VTK 3D within such a widget, then try as much as I can to wrap the 99 VTK classes with Shiboken. Thank you Matthew for these advices, I will let you know of my wrapping progress of VTK ! -- Nicolas SAUBAT Ingénieur Recherche et Développement Equipe GMCAO - Laboratoire TIMC-IMAG Pavillon Taillefer Allée des Alpes - Domaine de la Merci 38706 La Tronche Tel : (33)04 56 52 00 10 From matthew.woehlke at kitware.com Tue Dec 17 19:34:11 2013 From: matthew.woehlke at kitware.com (Matthew Woehlke) Date: Tue, 17 Dec 2013 13:34:11 -0500 Subject: [PySide] Binding C++/VTK code using Shiboken In-Reply-To: <52B01729.10604@imag.fr> References: <52A9DFBD.6030501@imag.fr> <52AB4174.4000306@imag.fr> <52B01729.10604@imag.fr> Message-ID: On 2013-12-17 04:19, Nicolas SAUBAT wrote: > On 12/13/2013 06:43 PM, Matthew Woehlke wrote: >> On 2013-12-13 12:18, Nicolas SAUBAT wrote: >>> If I have a C++ class based on both Qt and VTK (like this one : >>> http://camitk.imag.fr/apidocumentation/3.2/classcamitk_1_1RendererWidget.html), >>> I would be able to expose the VTK part using VTK's Python binder OR Qt >>> part using Shiboken, but not both. >> *AFAIK* this is correct. At least, I know that I've run into the same >> problem and didn't come up with a solution. >> >>> And then the solution seems to be to still use Shiboken, >>> and inject code in the wrapped classes (containing CPython code) in >>> order to tell it how to convert the Python object (PyObject) into a >>> VTKObject when necessary. Which seems difficult, from the C++ side, >>> regarding how VTK handles its VTKObjects. >>> Please let me know if I've misunderstood some points ! So I was talking to someone that claims you *can* get a vtkObject[Base?]* from a PyObject (i.e. there is a function for this in a VTK Python utility library). *If* that's correct, then you may be able to declare all of your VTK types as custom types and write code injections to do the C++ <-> Python mapping. This won't help if you're shiboken-wrapping something derived from a VTK class, however. In particular, you wouldn't be able to pass such a class to a VTK binding, and you'll be missing the base class members. > Have you already tried binding VTK with Shiboken on your own ? I started, but I was working from the angle of trying to implement it "in place" in the existing VTK repository, rather than approaching it as a separate project. Besides that I don't know that I could publish that code, it's not hugely likely to be very useful anyway. One thing I did "decide" when I was looking at it, however, is that you'll probably want to have a script auto-generate the typesystem XML in order to implement custom bindings for vtk get/set macros in order to do reasonable mapping of functions that take e.g. float*. IOW, there is lots of this: void SetColor(double*) void GetColor(double*) ...which should be wrapped with a code injection to take a PySequence of ≥ 3 (or 4) elements, attempt to fill a local (to the injection) double[3] variable with the elements, and pass that to the C++ function. And similar for the Get, to pass a local double[3] and turn it into a PySequence to return. The "trick" is that the size of the array is "known" only from the name of the macro that produces such functions, hence the need to parse the headers separately. (VTK's Python binding basically does something similar.) -- Matthew From jmohler at gamry.com Thu Dec 19 17:20:38 2013 From: jmohler at gamry.com (Joel B. Mohler) Date: Thu, 19 Dec 2013 11:20:38 -0500 Subject: [PySide] non-ascii chars in python 2 on windows Message-ID: <52B31CD6.6000806@gamry.com> The case correcting code in _utils.py has a bug on windows on python 2.7. The easy fix is included in the patch in the post-script. qt-project grumblings: I spent more time trying (and failing) to grok gerrit and gitorious than I did diagnosing and fixing this bug together. Consider me vexed! Also https://bugreports.qt-project.org doesn't acknowledge version 1.2.1 for PySide. Joel Patch: commit 9ded473872a5617df4b93e93c9db8d7b36f6f642 Author: Joel B. Mohler Date: Thu Dec 19 10:55:52 2013 -0500 use file system encoding instead of assumed 'ascii' diff --git a/PySide/_utils.py.in b/PySide/_utils.py.in index b8199fc..2c77ab4 100644 --- a/PySide/_utils.py.in +++ b/PySide/_utils.py.in @@ -45,16 +45,20 @@ if sys.platform == 'win32': if PY_2: def u(x): return unicode(x) + def u_fs(x): + return unicode(x, sys.getfilesystemencoding()) else: def u(x): return x + def u_fs(x): + return x def _get_win32_short_name(s): """ Returns short name """ buf_size = MAX_PATH for i in range(2): buf = create_unicode_buffer(u('\0') * (buf_size + 1)) - r = GetShortPathNameW(u(s), buf, buf_size) + r = GetShortPathNameW(u_fs(s), buf, buf_size) if r == 0: raise WinError() if r < buf_size: @@ -69,7 +73,7 @@ if sys.platform == 'win32': buf_size = MAX_PATH for i in range(2): buf = create_unicode_buffer(u('\0') * (buf_size + 1)) - r = GetLongPathNameW(u(s), buf, buf_size) + r = GetLongPathNameW(u_fs(s), buf, buf_size) if r == 0: raise WinError() if r < buf_size: From sean at seanfisk.com Thu Dec 19 20:57:59 2013 From: sean at seanfisk.com (Sean Fisk) Date: Thu, 19 Dec 2013 14:57:59 -0500 Subject: [PySide] PySide 1.2.1 API Docs In-Reply-To: <52A9DCBF.3070201@imag.fr> References: <52A5E8CC.2050200@imag.fr> <52A9DCBF.3070201@imag.fr> Message-ID: Hi everyone, Thanks to Nicolas’ work, we’ve added the ApiExtractor documentation to the site ! Thanks for the pull request, Nicolas. Sincerely, -- Sean Fisk On Thu, Dec 12, 2013 at 10:56 AM, Nicolas SAUBAT wrote: > Hi Sean, > > I've followed your advices and made a pull-request with a little add-on to > your (nice) build-docs script: > * patched Shiboken repository to modify CMakeLists.txt files in order to > get back apiextractor build documentation target > * build both shiboken and api_extractor targets in your script > > The documentation are located in > prefix/src/shiboken/build/[ApiExtractor]/doc/html. > > As it was my first experience with both Linux diff-patch and git, let me > know if I made some mistakes with your script ! > > Thanks again, > Nicolas. > > > On 12/10/2013 03:45 AM, Sean Fisk wrote: > > Hi Nicolas, > > I’d be happy to modify the script to create the API Extractor > documentation! There are two scripts in my Github repository- one to build the docs and the other to generate tarballs. Can you fork > my repo , make the > modifications, and create a pull request? > Then I’ll run the scripts again and upload the results to my Github pages. > If it's easier, you can just send a patch. > - Sean > > > -- > Sean Fisk > > > On Mon, Dec 9, 2013 at 10:59 AM, Nicolas SAUBAT wrote: > >> Hi, >> >> Thank you Sean for your work regarding the documentation. >> A few weeks ago, I was also looking for documentation regarding Shiboken >> (as a beginner I needed to start with some basic documentation). >> I wasn't aware of your email, this is why I also used the sources to >> build the Shiboken 1.2.1 documentation (not PySide API docs, at least for >> the moment). >> But, I noticed the API-Extractor documentation was not built, thus I >> modified the CMake configuration files in order to build it. >> Might it be interesting to add the missing API-Extractor documentation to >> your script / personnal page ? >> >> Anyway, I built the documentation as PDF files. I attached them, hoping >> they might help someone. >> >> Thanks, >> Nicolas. >> >> >> >> On 11/26/2013 08:12 PM, Sean Fisk wrote: >> >> Thanks, Anand, for testing the script out. Glad to have some confirmation >> of it working. >> >> Thanks, Roman, for uploading to ReadTheDocs and for your advice on >> building the docs. >> >> >> -- >> Sean Fisk >> >> >> On Tue, Nov 26, 2013 at 5:34 AM, Gadiyar, Anand wrote: >> >>> Sean, >>> >>> >>> >>> Thanks for this. I’ve just used your script on an Ubuntu box and it >>> works well! >>> >>> >>> >>> - Anand >>> >>> >>> >>> *From:* pyside-bounces+gadiyar=ti.com at qt-project.org [mailto: >>> pyside-bounces+gadiyar=ti.com at qt-project.org] *On Behalf Of *Roman Lacko >>> *Sent:* Tuesday, November 26, 2013 1:58 PM >>> *To:* Sean Fisk >>> *Cc:* PySide >>> *Subject:* Re: [PySide] PySide 1.2.1 API Docs >>> >>> >>> >>> Hi Sean, >>> >>> thanks for the hard work you spend on this. >>> >>> I will upload the docs to readthedocs server. >>> >>> Thanks >>> >>> Roman >>> >>> >>> >>> 2013/11/26 Sean Fisk >>> >>> Hello PySiders! >>> >>> After a monumental struggle I was able to achieve the goal of building >>> the PySide and Shiboken 1.2.1 API docs. Following in the footsteps of those >>> before me, I’ve uploaded them to Github Pagesfor use by the community. I’ve also created tarballs of the documentation >>> available for download. >>> >>> I’ve gathered the build process into a Bash script which is available in this >>> Github repo . I’ve tested it >>> on Mac OS X and CentOS, and it should work on most UNIX-like systems. If >>> anyone wants to hack on it, let me know if you have questions. >>> >>> During the build process, I stumbled upon a couple things: >>> >>> · qdoc3 from Qt 4.6 is needed to build API docs for PySide. >>> This is because WebXML support was buggy in Qt 4.7 and dropped in Qt 4.8, >>> and Shiboken uses this to generate the docs (thanks Roman Lacko). This is >>> very annoying because parts of Qt 4.6 must be configured and built for >>> qdoc3 to build correctly. >>> >>> · Shiboken has a documented --documentation-only flag but >>> refuses to actually accept it. But Shiboken doesn’t tell you which option >>> was invalid, only that it was “called with the wrong arguments.” This is >>> annoying but seems like it has an easy fix. >>> >>> The documentation build process is little convoluted in general. Some of >>> these issues seem like they are out of the hands of PySide, though. >>> >>> I hope these docs are able to help somebody out there! >>> >>> Thanks, >>> >>> -- >>> >>> Sean Fisk >>> >>> >>> _______________________________________________ >>> PySide mailing list >>> PySide at qt-project.org >>> http://lists.qt-project.org/mailman/listinfo/pyside >>> >>> >>> >> >> >> >> _______________________________________________ >> PySide mailing listPySide at qt-project.orghttp://lists.qt-project.org/mailman/listinfo/pyside >> >> >> -- >> Nicolas SAUBAT >> Ingénieur Recherche et Développement >> Equipe GMCAO - Laboratoire TIMC-IMAG >> Pavillon Taillefer >> Allée des Alpes - Domaine de la Merci >> 38706 La Tronche >> Tel : (33)04 56 52 00 10 >> >> >> _______________________________________________ >> PySide mailing list >> PySide at qt-project.org >> http://lists.qt-project.org/mailman/listinfo/pyside >> >> > > -- > Nicolas SAUBAT > Ingénieur Recherche et Développement > Equipe GMCAO - Laboratoire TIMC-IMAG > Pavillon Taillefer > Allée des Alpes - Domaine de la Merci > 38706 La Tronche > Tel : (33)04 56 52 00 10 > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From nicolas.saubat at imag.fr Fri Dec 20 15:31:28 2013 From: nicolas.saubat at imag.fr (Nicolas SAUBAT) Date: Fri, 20 Dec 2013 15:31:28 +0100 Subject: [PySide] PySide 1.2.1 API Docs In-Reply-To: References: <52A5E8CC.2050200@imag.fr> <52A9DCBF.3070201@imag.fr> Message-ID: <52B454C0.3050700@imag.fr> An HTML attachment was scrubbed... URL: From sean at seanfisk.com Fri Dec 20 17:38:04 2013 From: sean at seanfisk.com (Sean Fisk) Date: Fri, 20 Dec 2013 11:38:04 -0500 Subject: [PySide] PySide 1.2.1 API Docs In-Reply-To: <52B454C0.3050700@imag.fr> References: <52A5E8CC.2050200@imag.fr> <52A9DCBF.3070201@imag.fr> <52B454C0.3050700@imag.fr> Message-ID: Great, thanks Nicolas! -- Sean Fisk On Fri, Dec 20, 2013 at 9:31 AM, Nicolas SAUBAT wrote: > Thanks Sean, > > I've also put links in the PySide wiki page to your online documentation. > Hope that would help people looking for documentations ! > > Nicolas. > > > On 12/19/2013 08:57 PM, Sean Fisk wrote: > > Hi everyone, > > Thanks to Nicolas’ work, we’ve added the ApiExtractor documentation to the > site ! Thanks for the pull > request, Nicolas. > > Sincerely, > > > -- > Sean Fisk > > > On Thu, Dec 12, 2013 at 10:56 AM, Nicolas SAUBAT wrote: > >> Hi Sean, >> >> I've followed your advices and made a pull-request with a little add-on >> to your (nice) build-docs script: >> * patched Shiboken repository to modify CMakeLists.txt files in order to >> get back apiextractor build documentation target >> * build both shiboken and api_extractor targets in your script >> >> The documentation are located in >> prefix/src/shiboken/build/[ApiExtractor]/doc/html. >> >> As it was my first experience with both Linux diff-patch and git, let me >> know if I made some mistakes with your script ! >> >> Thanks again, >> Nicolas. >> >> >> On 12/10/2013 03:45 AM, Sean Fisk wrote: >> >> Hi Nicolas, >> >> I’d be happy to modify the script to create the API Extractor >> documentation! There are two scripts in my Github repository- one to build the docs and the other to generate tarballs. Can you fork >> my repo , make the >> modifications, and create a pull request? >> Then I’ll run the scripts again and upload the results to my Github pages. >> If it's easier, you can just send a patch. >> - Sean >> >> >> -- >> Sean Fisk >> >> >> On Mon, Dec 9, 2013 at 10:59 AM, Nicolas SAUBAT wrote: >> >>> Hi, >>> >>> Thank you Sean for your work regarding the documentation. >>> A few weeks ago, I was also looking for documentation regarding Shiboken >>> (as a beginner I needed to start with some basic documentation). >>> I wasn't aware of your email, this is why I also used the sources to >>> build the Shiboken 1.2.1 documentation (not PySide API docs, at least for >>> the moment). >>> But, I noticed the API-Extractor documentation was not built, thus I >>> modified the CMake configuration files in order to build it. >>> Might it be interesting to add the missing API-Extractor documentation >>> to your script / personnal page ? >>> >>> Anyway, I built the documentation as PDF files. I attached them, hoping >>> they might help someone. >>> >>> Thanks, >>> Nicolas. >>> >>> >>> >>> On 11/26/2013 08:12 PM, Sean Fisk wrote: >>> >>> Thanks, Anand, for testing the script out. Glad to have some >>> confirmation of it working. >>> >>> Thanks, Roman, for uploading to ReadTheDocs and for your advice on >>> building the docs. >>> >>> >>> -- >>> Sean Fisk >>> >>> >>> On Tue, Nov 26, 2013 at 5:34 AM, Gadiyar, Anand wrote: >>> >>>> Sean, >>>> >>>> >>>> >>>> Thanks for this. I’ve just used your script on an Ubuntu box and it >>>> works well! >>>> >>>> >>>> >>>> - Anand >>>> >>>> >>>> >>>> *From:* pyside-bounces+gadiyar=ti.com at qt-project.org [mailto: >>>> pyside-bounces+gadiyar=ti.com at qt-project.org] *On Behalf Of *Roman >>>> Lacko >>>> *Sent:* Tuesday, November 26, 2013 1:58 PM >>>> *To:* Sean Fisk >>>> *Cc:* PySide >>>> *Subject:* Re: [PySide] PySide 1.2.1 API Docs >>>> >>>> >>>> >>>> Hi Sean, >>>> >>>> thanks for the hard work you spend on this. >>>> >>>> I will upload the docs to readthedocs server. >>>> >>>> Thanks >>>> >>>> Roman >>>> >>>> >>>> >>>> 2013/11/26 Sean Fisk >>>> >>>> Hello PySiders! >>>> >>>> After a monumental struggle I was able to achieve the goal of building >>>> the PySide and Shiboken 1.2.1 API docs. Following in the footsteps of those >>>> before me, I’ve uploaded them to Github Pagesfor use by the community. I’ve also created tarballs of the documentation >>>> available for download. >>>> >>>> I’ve gathered the build process into a Bash script which is available >>>> in this Github repo . I’ve >>>> tested it on Mac OS X and CentOS, and it should work on most UNIX-like >>>> systems. If anyone wants to hack on it, let me know if you have questions. >>>> >>>> During the build process, I stumbled upon a couple things: >>>> >>>> · qdoc3 from Qt 4.6 is needed to build API docs for PySide. >>>> This is because WebXML support was buggy in Qt 4.7 and dropped in Qt 4.8, >>>> and Shiboken uses this to generate the docs (thanks Roman Lacko). This is >>>> very annoying because parts of Qt 4.6 must be configured and built for >>>> qdoc3 to build correctly. >>>> >>>> · Shiboken has a documented --documentation-only flag but >>>> refuses to actually accept it. But Shiboken doesn’t tell you which option >>>> was invalid, only that it was “called with the wrong arguments.” This is >>>> annoying but seems like it has an easy fix. >>>> >>>> The documentation build process is little convoluted in general. Some >>>> of these issues seem like they are out of the hands of PySide, though. >>>> >>>> I hope these docs are able to help somebody out there! >>>> >>>> Thanks, >>>> >>>> -- >>>> >>>> Sean Fisk >>>> >>>> >>>> _______________________________________________ >>>> PySide mailing list >>>> PySide at qt-project.org >>>> http://lists.qt-project.org/mailman/listinfo/pyside >>>> >>>> >>>> >>> >>> >>> >>> _______________________________________________ >>> PySide mailing listPySide at qt-project.orghttp://lists.qt-project.org/mailman/listinfo/pyside >>> >>> >>> -- >>> Nicolas SAUBAT >>> Ingénieur Recherche et Développement >>> Equipe GMCAO - Laboratoire TIMC-IMAG >>> Pavillon Taillefer >>> Allée des Alpes - Domaine de la Merci >>> 38706 La Tronche >>> Tel : (33)04 56 52 00 10 >>> >>> >>> _______________________________________________ >>> PySide mailing list >>> PySide at qt-project.org >>> http://lists.qt-project.org/mailman/listinfo/pyside >>> >>> >> >> -- >> Nicolas SAUBAT >> Ingénieur Recherche et Développement >> Equipe GMCAO - Laboratoire TIMC-IMAG >> Pavillon Taillefer >> Allée des Alpes - Domaine de la Merci >> 38706 La Tronche >> Tel : (33)04 56 52 00 10 >> >> > > -- > Nicolas SAUBAT > Ingénieur Recherche et Développement > Equipe GMCAO - Laboratoire TIMC-IMAG > Pavillon Taillefer > Allée des Alpes - Domaine de la Merci > 38706 La Tronche > Tel : (33)04 56 52 00 10 > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From krecoun at gmail.com Sun Dec 22 18:15:41 2013 From: krecoun at gmail.com (=?ISO-8859-2?Q?Vojt=ECch_Pol=E1=B9ek?=) Date: Sun, 22 Dec 2013 18:15:41 +0100 Subject: [PySide] Question from a newbie Message-ID: <52B71E3D.6000803@gmail.com> Greetings, my name is Vojtěch Polášek and I am a blind student from czech Republic. I am creating an application in Pyside with Python 3.2. I would like to create a sudoku game accessible for blind and visually impaired people. I have created a main window, added a widget which contains 81 buttons in a grid layout. Now my idea is, that after pressing a button, that button would disappear and would be replaced by some other controll which would allow you to change the value. I chose QSpinBox for now. This step works well, although I had to implement my own eventfilter, because QT in Linux uses arrows to browse available elements on the screen. Never mind. Now this is the way in which I replace a button with a spinbox. This function is connected to the QPushButton.clicked signal: def editValue(self): print ('editing') senderpos = self.grid.getItemPosition(self.grid.indexOf(self.sender())) self.grid.addWidget(self.spinbox, senderpos[0], senderpos[1]) print ('added') self.spinbox.setValue(int(self.sender().text())) print ('value set') self.spinbox.show() print('showed') self.spinbox.setFocus() print('focused') self.spinbox.editingFinished.connect(self.storeValue) print('connected') Don't mind those print statements, they are there for debugging purposes, because I haven't found a way of debugging Pyside with PDB. The problem is, that this signal is also called after I press a button and this function is executed. I don't manipulate with spinbox in any manner. Only thing that is set is its accepted range of input. What could be the problem? I am attaching the source code. Thank you very much, Vojtěch Polášek -------------- next part -------------- A non-text attachment was scrubbed... Name: layout.py Type: text/x-python Size: 2601 bytes Desc: not available URL: From a.richi at bluewin.ch Tue Dec 24 11:14:08 2013 From: a.richi at bluewin.ch (Aaron Richiger) Date: Tue, 24 Dec 2013 11:14:08 +0100 Subject: [PySide] Question from a newbie In-Reply-To: <52B71E3D.6000803@gmail.com> References: <52B71E3D.6000803@gmail.com> Message-ID: <52B95E70.707@bluewin.ch> Hello Vojtech Impressive what you are able to do!!! I can't find my bugs with good eyes and have no idea how one would find them without seeing the code. I changed a few things in your file and hope, the resulting solution fits your needs: - fixed rowCount of your sudoku (was 10, now 9) - overwrote QPushButton and QSpinBox to store their index and to implement custom keyPressEvent behaviour - navigate using arrows, start editing by hitting enter or return. - change value of the spinbox using arrows, finish editing by hitting enter, continue navigating I hope this helps! If you have further questions, feel free to ask again! Merry Christmas! Aaron Am 22.12.2013 18:15, schrieb Vojtěch Polášek: > Greetings, > my name is Vojtěch Polášek and I am a blind student from czech Republic. > I am creating an application in Pyside with Python 3.2. I would like to > create a sudoku game accessible for blind and visually impaired people. > I have created a main window, added a widget which contains 81 buttons > in a grid layout. Now my idea is, that after pressing a button, that > button would disappear and would be replaced by some other controll > which would allow you to change the value. I chose QSpinBox for now. > This step works well, although I had to implement my own eventfilter, > because QT in Linux uses arrows to browse available elements on the > screen. Never mind. > Now this is the way in which I replace a button with a spinbox. This > function is connected to the QPushButton.clicked signal: > def editValue(self): > print ('editing') > senderpos = > self.grid.getItemPosition(self.grid.indexOf(self.sender())) > self.grid.addWidget(self.spinbox, senderpos[0], senderpos[1]) > print ('added') > self.spinbox.setValue(int(self.sender().text())) > print ('value set') > self.spinbox.show() > print('showed') > self.spinbox.setFocus() > print('focused') > self.spinbox.editingFinished.connect(self.storeValue) > print('connected') > > Don't mind those print statements, they are there for debugging > purposes, because I haven't found a way of debugging Pyside with PDB. > The problem is, that this signal is also called after I press a button > and this function is executed. I don't manipulate with spinbox in any > manner. Only thing that is set is its accepted range of input. > What could be the problem? > I am attaching the source code. > Thank you very much, > Vojtěch Polášek > > > _______________________________________________ > PySide mailing list > PySide at qt-project.org > http://lists.qt-project.org/mailman/listinfo/pyside -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: layout.py Type: text/x-python Size: 3413 bytes Desc: not available URL: From krecoun at gmail.com Tue Dec 24 11:30:31 2013 From: krecoun at gmail.com (=?UTF-8?B?Vm9qdMSbY2ggUG9sw6HFoWVr?=) Date: Tue, 24 Dec 2013 11:30:31 +0100 Subject: [PySide] Question from a newbie In-Reply-To: <52B95E70.707@bluewin.ch> References: <52B71E3D.6000803@gmail.com> <52B95E70.707@bluewin.ch> Message-ID: <52B96247.4060007@gmail.com> Hi, Thank you very much for your help, nice Christmas present from you. I wanted to do that without subclassing anything, but now I see that I will have to do that sometimes. Thank you again and mery Christmas, Vojta Dne 24.12.2013 11:14, Aaron Richiger napsal(a): > Hello Vojtech > > Impressive what you are able to do!!! I can't find my bugs with good > eyes and have no idea how one would find them without seeing the code. > I changed a few things in your file and hope, the resulting solution > fits your needs: > > - fixed rowCount of your sudoku (was 10, now 9) > - overwrote QPushButton and QSpinBox to store their index and to > implement custom keyPressEvent behaviour > - navigate using arrows, start editing by hitting enter or return. > - change value of the spinbox using arrows, finish editing by hitting > enter, continue navigating > > I hope this helps! If you have further questions, feel free to ask again! > > Merry Christmas! Aaron > > > > > > Am 22.12.2013 18:15, schrieb Vojtěch Polášek: >> Greetings, >> my name is Vojtěch Polášek and I am a blind student from czech Republic. >> I am creating an application in Pyside with Python 3.2. I would like to >> create a sudoku game accessible for blind and visually impaired people. >> I have created a main window, added a widget which contains 81 buttons >> in a grid layout. Now my idea is, that after pressing a button, that >> button would disappear and would be replaced by some other controll >> which would allow you to change the value. I chose QSpinBox for now. >> This step works well, although I had to implement my own eventfilter, >> because QT in Linux uses arrows to browse available elements on the >> screen. Never mind. >> Now this is the way in which I replace a button with a spinbox. This >> function is connected to the QPushButton.clicked signal: >> def editValue(self): >> print ('editing') >> senderpos = >> self.grid.getItemPosition(self.grid.indexOf(self.sender())) >> self.grid.addWidget(self.spinbox, senderpos[0], senderpos[1]) >> print ('added') >> self.spinbox.setValue(int(self.sender().text())) >> print ('value set') >> self.spinbox.show() >> print('showed') >> self.spinbox.setFocus() >> print('focused') >> self.spinbox.editingFinished.connect(self.storeValue) >> print('connected') >> >> Don't mind those print statements, they are there for debugging >> purposes, because I haven't found a way of debugging Pyside with PDB. >> The problem is, that this signal is also called after I press a button >> and this function is executed. I don't manipulate with spinbox in any >> manner. Only thing that is set is its accepted range of input. >> What could be the problem? >> I am attaching the source code. >> Thank you very much, >> Vojtěch Polášek >> >> >> _______________________________________________ >> PySide mailing list >> PySide at qt-project.org >> http://lists.qt-project.org/mailman/listinfo/pyside > > > > _______________________________________________ > PySide mailing list > PySide at qt-project.org > http://lists.qt-project.org/mailman/listinfo/pyside -------------- next part -------------- An HTML attachment was scrubbed... URL: From backup.rlacko at gmail.com Mon Dec 30 13:43:26 2013 From: backup.rlacko at gmail.com (Roman Lacko) Date: Mon, 30 Dec 2013 13:43:26 +0100 Subject: [PySide] PySide 1.2.1 API Docs In-Reply-To: References: <52A5E8CC.2050200@imag.fr> <52A9DCBF.3070201@imag.fr> <52B454C0.3050700@imag.fr> Message-ID: Sean, I uploaded the documentation you generated to official pyside repository and updated the links on wiki. Thanks again! 2013/12/20 Sean Fisk > Great, thanks Nicolas! > > > -- > Sean Fisk > > > On Fri, Dec 20, 2013 at 9:31 AM, Nicolas SAUBAT wrote: > >> Thanks Sean, >> >> I've also put links in the PySide wiki page to your online documentation. >> Hope that would help people looking for documentations ! >> >> Nicolas. >> >> >> On 12/19/2013 08:57 PM, Sean Fisk wrote: >> >> Hi everyone, >> >> Thanks to Nicolas’ work, we’ve added the ApiExtractor documentation to the >> site ! Thanks for the pull >> request, Nicolas. >> >> Sincerely, >> >> >> -- >> Sean Fisk >> >> >> On Thu, Dec 12, 2013 at 10:56 AM, Nicolas SAUBAT wrote: >> >>> Hi Sean, >>> >>> I've followed your advices and made a pull-request with a little add-on >>> to your (nice) build-docs script: >>> * patched Shiboken repository to modify CMakeLists.txt files in order >>> to get back apiextractor build documentation target >>> * build both shiboken and api_extractor targets in your script >>> >>> The documentation are located in >>> prefix/src/shiboken/build/[ApiExtractor]/doc/html. >>> >>> As it was my first experience with both Linux diff-patch and git, let me >>> know if I made some mistakes with your script ! >>> >>> Thanks again, >>> Nicolas. >>> >>> >>> On 12/10/2013 03:45 AM, Sean Fisk wrote: >>> >>> Hi Nicolas, >>> >>> I’d be happy to modify the script to create the API Extractor >>> documentation! There are two scripts in my Github repository- one to build the docs and the other to generate tarballs. Can you fork >>> my repo , make the >>> modifications, and create a pull request? >>> Then I’ll run the scripts again and upload the results to my Github pages. >>> If it's easier, you can just send a patch. >>> - Sean >>> >>> >>> -- >>> Sean Fisk >>> >>> >>> On Mon, Dec 9, 2013 at 10:59 AM, Nicolas SAUBAT wrote: >>> >>>> Hi, >>>> >>>> Thank you Sean for your work regarding the documentation. >>>> A few weeks ago, I was also looking for documentation regarding >>>> Shiboken (as a beginner I needed to start with some basic documentation). >>>> I wasn't aware of your email, this is why I also used the sources to >>>> build the Shiboken 1.2.1 documentation (not PySide API docs, at least for >>>> the moment). >>>> But, I noticed the API-Extractor documentation was not built, thus I >>>> modified the CMake configuration files in order to build it. >>>> Might it be interesting to add the missing API-Extractor documentation >>>> to your script / personnal page ? >>>> >>>> Anyway, I built the documentation as PDF files. I attached them, hoping >>>> they might help someone. >>>> >>>> Thanks, >>>> Nicolas. >>>> >>>> >>>> >>>> On 11/26/2013 08:12 PM, Sean Fisk wrote: >>>> >>>> Thanks, Anand, for testing the script out. Glad to have some >>>> confirmation of it working. >>>> >>>> Thanks, Roman, for uploading to ReadTheDocs and for your advice on >>>> building the docs. >>>> >>>> >>>> -- >>>> Sean Fisk >>>> >>>> >>>> On Tue, Nov 26, 2013 at 5:34 AM, Gadiyar, Anand wrote: >>>> >>>>> Sean, >>>>> >>>>> >>>>> >>>>> Thanks for this. I’ve just used your script on an Ubuntu box and it >>>>> works well! >>>>> >>>>> >>>>> >>>>> - Anand >>>>> >>>>> >>>>> >>>>> *From:* pyside-bounces+gadiyar=ti.com at qt-project.org [mailto: >>>>> pyside-bounces+gadiyar=ti.com at qt-project.org] *On Behalf Of *Roman >>>>> Lacko >>>>> *Sent:* Tuesday, November 26, 2013 1:58 PM >>>>> *To:* Sean Fisk >>>>> *Cc:* PySide >>>>> *Subject:* Re: [PySide] PySide 1.2.1 API Docs >>>>> >>>>> >>>>> >>>>> Hi Sean, >>>>> >>>>> thanks for the hard work you spend on this. >>>>> >>>>> I will upload the docs to readthedocs server. >>>>> >>>>> Thanks >>>>> >>>>> Roman >>>>> >>>>> >>>>> >>>>> 2013/11/26 Sean Fisk >>>>> >>>>> Hello PySiders! >>>>> >>>>> After a monumental struggle I was able to achieve the goal of building >>>>> the PySide and Shiboken 1.2.1 API docs. Following in the footsteps of those >>>>> before me, I’ve uploaded them to Github Pagesfor use by the community. I’ve also created tarballs of the documentation >>>>> available for download. >>>>> >>>>> I’ve gathered the build process into a Bash script which is available >>>>> in this Github repo . I’ve >>>>> tested it on Mac OS X and CentOS, and it should work on most UNIX-like >>>>> systems. If anyone wants to hack on it, let me know if you have questions. >>>>> >>>>> During the build process, I stumbled upon a couple things: >>>>> >>>>> · qdoc3 from Qt 4.6 is needed to build API docs for PySide. >>>>> This is because WebXML support was buggy in Qt 4.7 and dropped in Qt 4.8, >>>>> and Shiboken uses this to generate the docs (thanks Roman Lacko). This is >>>>> very annoying because parts of Qt 4.6 must be configured and built for >>>>> qdoc3 to build correctly. >>>>> >>>>> · Shiboken has a documented --documentation-only flag but >>>>> refuses to actually accept it. But Shiboken doesn’t tell you which option >>>>> was invalid, only that it was “called with the wrong arguments.” This is >>>>> annoying but seems like it has an easy fix. >>>>> >>>>> The documentation build process is little convoluted in general. Some >>>>> of these issues seem like they are out of the hands of PySide, though. >>>>> >>>>> I hope these docs are able to help somebody out there! >>>>> >>>>> Thanks, >>>>> >>>>> -- >>>>> >>>>> Sean Fisk >>>>> >>>>> >>>>> _______________________________________________ >>>>> PySide mailing list >>>>> PySide at qt-project.org >>>>> http://lists.qt-project.org/mailman/listinfo/pyside >>>>> >>>>> >>>>> >>>> >>>> >>>> >>>> _______________________________________________ >>>> PySide mailing listPySide at qt-project.orghttp://lists.qt-project.org/mailman/listinfo/pyside >>>> >>>> >>>> -- >>>> Nicolas SAUBAT >>>> Ingénieur Recherche et Développement >>>> Equipe GMCAO - Laboratoire TIMC-IMAG >>>> Pavillon Taillefer >>>> Allée des Alpes - Domaine de la Merci >>>> 38706 La Tronche >>>> Tel : (33)04 56 52 00 10 >>>> >>>> >>>> _______________________________________________ >>>> PySide mailing list >>>> PySide at qt-project.org >>>> http://lists.qt-project.org/mailman/listinfo/pyside >>>> >>>> >>> >>> -- >>> Nicolas SAUBAT >>> Ingénieur Recherche et Développement >>> Equipe GMCAO - Laboratoire TIMC-IMAG >>> Pavillon Taillefer >>> Allée des Alpes - Domaine de la Merci >>> 38706 La Tronche >>> Tel : (33)04 56 52 00 10 >>> >>> >> >> -- >> Nicolas SAUBAT >> Ingénieur Recherche et Développement >> Equipe GMCAO - Laboratoire TIMC-IMAG >> Pavillon Taillefer >> Allée des Alpes - Domaine de la Merci >> 38706 La Tronche >> Tel : (33)04 56 52 00 10 >> >> > > _______________________________________________ > PySide mailing list > PySide at qt-project.org > http://lists.qt-project.org/mailman/listinfo/pyside > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From sean at seanfisk.com Tue Dec 31 07:24:31 2013 From: sean at seanfisk.com (Sean Fisk) Date: Tue, 31 Dec 2013 01:24:31 -0500 Subject: [PySide] PySide 1.2.1 API Docs In-Reply-To: References: <52A5E8CC.2050200@imag.fr> <52A9DCBF.3070201@imag.fr> <52B454C0.3050700@imag.fr> Message-ID: Thanks for your help, Roman. Much appreciated. -- Sean Fisk On Mon, Dec 30, 2013 at 7:43 AM, Roman Lacko wrote: > Sean, I uploaded the documentation you generated to official pyside > repository and updated the links on wiki. > > Thanks again! > > 2013/12/20 Sean Fisk > >> Great, thanks Nicolas! >> >> >> -- >> Sean Fisk >> >> >> On Fri, Dec 20, 2013 at 9:31 AM, Nicolas SAUBAT wrote: >> >>> Thanks Sean, >>> >>> I've also put links in the PySide wiki page to your online documentation. >>> Hope that would help people looking for documentations ! >>> >>> Nicolas. >>> >>> >>> On 12/19/2013 08:57 PM, Sean Fisk wrote: >>> >>> Hi everyone, >>> >>> Thanks to Nicolas’ work, we’ve added the ApiExtractor documentation to the >>> site ! Thanks for the pull >>> request, Nicolas. >>> >>> Sincerely, >>> >>> >>> -- >>> Sean Fisk >>> >>> >>> On Thu, Dec 12, 2013 at 10:56 AM, Nicolas SAUBAT >> > wrote: >>> >>>> Hi Sean, >>>> >>>> I've followed your advices and made a pull-request with a little add-on >>>> to your (nice) build-docs script: >>>> * patched Shiboken repository to modify CMakeLists.txt files in order >>>> to get back apiextractor build documentation target >>>> * build both shiboken and api_extractor targets in your script >>>> >>>> The documentation are located in >>>> prefix/src/shiboken/build/[ApiExtractor]/doc/html. >>>> >>>> As it was my first experience with both Linux diff-patch and git, let >>>> me know if I made some mistakes with your script ! >>>> >>>> Thanks again, >>>> Nicolas. >>>> >>>> >>>> On 12/10/2013 03:45 AM, Sean Fisk wrote: >>>> >>>> Hi Nicolas, >>>> >>>> I’d be happy to modify the script to create the API Extractor >>>> documentation! There are two scripts in my Github repository- one to build the docs and the other to generate tarballs. Can you fork >>>> my repo , make the >>>> modifications, and create a pull request? >>>> Then I’ll run the scripts again and upload the results to my Github pages. >>>> If it's easier, you can just send a patch. >>>> - Sean >>>> >>>> >>>> -- >>>> Sean Fisk >>>> >>>> >>>> On Mon, Dec 9, 2013 at 10:59 AM, Nicolas SAUBAT >>> > wrote: >>>> >>>>> Hi, >>>>> >>>>> Thank you Sean for your work regarding the documentation. >>>>> A few weeks ago, I was also looking for documentation regarding >>>>> Shiboken (as a beginner I needed to start with some basic documentation). >>>>> I wasn't aware of your email, this is why I also used the sources to >>>>> build the Shiboken 1.2.1 documentation (not PySide API docs, at least for >>>>> the moment). >>>>> But, I noticed the API-Extractor documentation was not built, thus I >>>>> modified the CMake configuration files in order to build it. >>>>> Might it be interesting to add the missing API-Extractor documentation >>>>> to your script / personnal page ? >>>>> >>>>> Anyway, I built the documentation as PDF files. I attached them, >>>>> hoping they might help someone. >>>>> >>>>> Thanks, >>>>> Nicolas. >>>>> >>>>> >>>>> >>>>> On 11/26/2013 08:12 PM, Sean Fisk wrote: >>>>> >>>>> Thanks, Anand, for testing the script out. Glad to have some >>>>> confirmation of it working. >>>>> >>>>> Thanks, Roman, for uploading to ReadTheDocs and for your advice on >>>>> building the docs. >>>>> >>>>> >>>>> -- >>>>> Sean Fisk >>>>> >>>>> >>>>> On Tue, Nov 26, 2013 at 5:34 AM, Gadiyar, Anand wrote: >>>>> >>>>>> Sean, >>>>>> >>>>>> >>>>>> >>>>>> Thanks for this. I’ve just used your script on an Ubuntu box and it >>>>>> works well! >>>>>> >>>>>> >>>>>> >>>>>> - Anand >>>>>> >>>>>> >>>>>> >>>>>> *From:* pyside-bounces+gadiyar=ti.com at qt-project.org [mailto: >>>>>> pyside-bounces+gadiyar=ti.com at qt-project.org] *On Behalf Of *Roman >>>>>> Lacko >>>>>> *Sent:* Tuesday, November 26, 2013 1:58 PM >>>>>> *To:* Sean Fisk >>>>>> *Cc:* PySide >>>>>> *Subject:* Re: [PySide] PySide 1.2.1 API Docs >>>>>> >>>>>> >>>>>> >>>>>> Hi Sean, >>>>>> >>>>>> thanks for the hard work you spend on this. >>>>>> >>>>>> I will upload the docs to readthedocs server. >>>>>> >>>>>> Thanks >>>>>> >>>>>> Roman >>>>>> >>>>>> >>>>>> >>>>>> 2013/11/26 Sean Fisk >>>>>> >>>>>> Hello PySiders! >>>>>> >>>>>> After a monumental struggle I was able to achieve the goal of >>>>>> building the PySide and Shiboken 1.2.1 API docs. Following in the footsteps >>>>>> of those before me, I’ve uploaded them to Github Pagesfor use by the community. I’ve also created tarballs of the documentation >>>>>> available for download. >>>>>> >>>>>> I’ve gathered the build process into a Bash script which is available >>>>>> in this Github repo . I’ve >>>>>> tested it on Mac OS X and CentOS, and it should work on most UNIX-like >>>>>> systems. If anyone wants to hack on it, let me know if you have questions. >>>>>> >>>>>> During the build process, I stumbled upon a couple things: >>>>>> >>>>>> · qdoc3 from Qt 4.6 is needed to build API docs for PySide. >>>>>> This is because WebXML support was buggy in Qt 4.7 and dropped in Qt 4.8, >>>>>> and Shiboken uses this to generate the docs (thanks Roman Lacko). This is >>>>>> very annoying because parts of Qt 4.6 must be configured and built for >>>>>> qdoc3 to build correctly. >>>>>> >>>>>> · Shiboken has a documented --documentation-only flag but >>>>>> refuses to actually accept it. But Shiboken doesn’t tell you which option >>>>>> was invalid, only that it was “called with the wrong arguments.” This is >>>>>> annoying but seems like it has an easy fix. >>>>>> >>>>>> The documentation build process is little convoluted in general. Some >>>>>> of these issues seem like they are out of the hands of PySide, though. >>>>>> >>>>>> I hope these docs are able to help somebody out there! >>>>>> >>>>>> Thanks, >>>>>> >>>>>> -- >>>>>> >>>>>> Sean Fisk >>>>>> >>>>>> >>>>>> _______________________________________________ >>>>>> PySide mailing list >>>>>> PySide at qt-project.org >>>>>> http://lists.qt-project.org/mailman/listinfo/pyside >>>>>> >>>>>> >>>>>> >>>>> >>>>> >>>>> >>>>> _______________________________________________ >>>>> PySide mailing listPySide at qt-project.orghttp://lists.qt-project.org/mailman/listinfo/pyside >>>>> >>>>> >>>>> -- >>>>> Nicolas SAUBAT >>>>> Ingénieur Recherche et Développement >>>>> Equipe GMCAO - Laboratoire TIMC-IMAG >>>>> Pavillon Taillefer >>>>> Allée des Alpes - Domaine de la Merci >>>>> 38706 La Tronche >>>>> Tel : (33)04 56 52 00 10 >>>>> >>>>> >>>>> _______________________________________________ >>>>> PySide mailing list >>>>> PySide at qt-project.org >>>>> http://lists.qt-project.org/mailman/listinfo/pyside >>>>> >>>>> >>>> >>>> -- >>>> Nicolas SAUBAT >>>> Ingénieur Recherche et Développement >>>> Equipe GMCAO - Laboratoire TIMC-IMAG >>>> Pavillon Taillefer >>>> Allée des Alpes - Domaine de la Merci >>>> 38706 La Tronche >>>> Tel : (33)04 56 52 00 10 >>>> >>>> >>> >>> -- >>> Nicolas SAUBAT >>> Ingénieur Recherche et Développement >>> Equipe GMCAO - Laboratoire TIMC-IMAG >>> Pavillon Taillefer >>> Allée des Alpes - Domaine de la Merci >>> 38706 La Tronche >>> Tel : (33)04 56 52 00 10 >>> >>> >> >> _______________________________________________ >> PySide mailing list >> PySide at qt-project.org >> http://lists.qt-project.org/mailman/listinfo/pyside >> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: