[PyKDE] QTextEdit.selectAll() bug?
Hi folks, I need to unselect everything in a QTextEdit-derived widget. Based on the C++ Qt API, it would seem that calling selectAll(false) should do it. However, I can't seem to get it to work with PyQt 3.6 No matter what value I pass this method, 0 or otherwise, it always seems to use the default value of the method's argument, namely 'true', which selects everything. Not quite what I want it to do! Is this normal? Am I overlooking something? If not, in the meanwhile, how can I cleanly unselect everything in my widget? Thanks in advance! -- S. ___ PyKDE mailing list[EMAIL PROTECTED] http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
[PyKDE] QTextEdit.selectAll() bug? -- Precisions
I heard Sundance said: > No matter what value I pass this method, 0 or otherwise, it always > seems to use the default value of the method's argument, namely > 'true', which selects everything. Not quite what I want it to do! Okay, so I prodded at eric3's sources, and it does use selectAll(0) to deselect everything, and it -works-. Now I'm confused. Could it be that the mode I use the QTextEdit widget in (LogText) screws this method up somehow? *fiddle, fiddle* Okay, so when I switch to RichText, selectAll(0) works, and unselects everything. Now I'm totally confused. Is this a Qt bug then? Is there a workaround? NB: I'm using Qt 3.1.2, Python 2.2.2, PyQt 3.6. Sorry I forgot to mention it the first time. -- S. the unlucky ___ PyKDE mailing list[EMAIL PROTECTED] http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
[PyKDE] QTextEdit/LogText color question
Hello people, I'm seeking to use the LogText kind of QTextEdit. I want to set the *default* text color in that widget. So far I've been unsuccessful. I've tried to use my_textedit_widget.setColor(). Doesn't work. So I've begun exploring the whole stylesheeting system, to no avail so far. I have a feeling that the solution to my problem could be as simple as: my_textedit_widget.styleSheet().item(*default item*).setColor() But I have no idea what '*default item*' should be. "qt" didn't work. "html" didn't work. "body" didn't work. "font" didn't work. "" (empty string) didn't work. Gah! In all cases, the text remained black. I suppose that printing '' in my widget's text right at creation time, and leaving this tag unclosed for the time being, would do it. But it feels awfully kludgy to me. I'm sure I'm missing the 'right' way to do it. Does anyone have any clue about what that 'right' way would be? Thanks in advance! -- S. ___ PyKDE mailing list[EMAIL PROTECTED] http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] QTextEdit/LogText color question
I heard Vio said: > How about: > > my_favorite_color = QColor(11,22,33) # change to real color values > my_textedit_widget.setPaletteForegroundColor(my_favorite_color) It works great! Many many thanks, Vio! :) -- S. ___ PyKDE mailing list[EMAIL PROTECTED] http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] ANN: new eric3 snapshot available
I heard Detlev Offenbach said: > This snapshot is available via > http://www.die-offenbachs.de/detlev/snapshots/eric-snapshot-20030817.tar.gz This totally rocks. :D Thank you for all the work, Detlev! I've made an ebuild to make it easier for people to give it a try. Eric is growing from great to awesome at an interestingly quick pace. :) Off to play with the new features -- bye people! -- S. DESCRIPTION="The eric3 Python IDE" IUSE="" MY_P="${PN}-snapshot-${PV##*.}" SRC_URI="http://www.die-offenbachs.de/detlev/snapshots/${MY_P}.tar.gz"; HOMEPAGE="http://www.die-offenbachs.de/detlev/eric3.html"; SLOT="0" LICENSE="GPL-2" KEYWORDS="x86" DEPEND="virtual/glibc sys-devel/libtool >=x11-libs/qt-3.0.4.1 >=dev-python/qscintilla-1.52 >=dev-lang/python-2.2.1 >=dev-python/sip-3.6 >=dev-python/PyQt-3.6-r1 !dev-python/bicyclerepair" src_install() { cd ${WORKDIR}/${MY_P} python install.py \ -b /usr/bin \ -i ${D} dodoc HISTORY LICENSE.GPL README eric/README-scripting.txt THANKS }
[PyKDE] Garbage collection of signal/slot association?
Hello, Here's a silly question: given two qobjects A and B, and a connection between A.SomeSignal and B.SomeSlot, does the connection get garbage collected upon deletion of either A or B? Just wondering. :) -- S. ___ PyKDE mailing list[EMAIL PROTECTED] http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] Garbage collection of signal/slot association?
I heard Phil Thompson said: > If it doesn't then it's a bug. Oh, don't worry, I've not had a problem with it -- I was just wondering, is all. :) Thank you, Phil! -- S. ___ PyKDE mailing list[EMAIL PROTECTED] http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
[PyKDE] KTrader woes?
Hiya, I'm prodding at the under-the-hood niftiness that makes KDE's beauty and strength, using the Python bindings, but so far I've not had much success, I am sorry to report. For example, this code: from kio import * offer = KTrader.self().query("text/html") ... causes Python to segfault. Is this a bug? Did I do something wrong? In case this is a bug, what can I do to help provide more information? NB: I'm on KDE 3.1.3 and PyKDE 3.7.4. -- S. ___ PyKDE mailing list[EMAIL PROTECTED] http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] KTrader woes?
I heard Jim Bublitz said: > It returns a 7 item list here (exact same code as above in a > KApplication). Ah. The 'in a KApplication' part may actually be the crucial point. :) > Can you provide a *short*, complete example > program that segfaults on this? Already did. 0:) #!/bin/env python from kio import * offer = KTrader.self().query("text/html") print "If you read this, then it has worked. Uh." I assume that it is not expected to work outside a KApplication, then? Maybe there should be a way to raise an exception rather than crash when this is called outside a KApplication...? That was the behavior I expected anyway, so when I tried the KTrader trick on its own I assumed that it would either 1) work on its own, or 2) require some QApplication-like class to have been instanciated, in which case it would warn me. Guess I was wrong about the 'warn me' part. > There are a couple of programs in examples/ that use KTrader > (pyParts.py, pyParts_1.py don't work too well at the moment > though). If you run examples/mimetype.py, the OfferList tab > results are from a KTrader call -- does that work? It does. I rewrote my little example above adding a KApplication instanciation just before the call to KTrader.self().query, and it works, whee! Well, more precisely, it works if I copy the KCmdLineArgs.init line from mimetype.py. If I call KApplication([], "SomeName") it dies. Apparently KApplication REQUIRES a non-empty list as its first argument, unlike QApplication (with which the [] trick works). Alright, so. Erm. :) I may be wrong about this as well, but I still sort of think there are more elegant ways to let the user know he's done something wrong than crash the full interpreter. =) Is there any way we can help make it so? -- S. ___ PyKDE mailing list[EMAIL PROTECTED] http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] KTrader woes?
I heard Jim Bublitz said: > You'd have to talk to KDE and TrollTech about that - that's > built-in behaviour in the KDE/Qt C++ libs. Some things do throw > an exception/error msgs, like trying to use widgets without a > QApplication/KApplication instance exisiting (although the msg > usually complains about a missing QPainter instance). I would > imagine KTrader is looking for some other connection the > KApplication establishes with KDE. Oookay. Well, darn! Thanks for the explanation. I'll go to bed a tad less ignorant tonight. :) > Nah - you got a segfault. Just not a very delicate warning. :) Yeah. You'd think it would at LEAST have the grace of saying something like, "Ooh, something bad happened, sir, I'm gonna have to crash, but beforehand I wish to beg you to accept my apologies! *blarg*" This being said -- any remote chance that we could be able to install a signal handler, so that we can tell the user, "Whoops, something bad happened in method of class . Did you think of creating a KApplication instance before calling this?" or something like that? And then there's KApplication itself, where checking that the first argument is a non-empty list ought to be relatively trivial, no...? Or does the way sip works prevent such checks at the Python level? Or maybe it's just not worth it at all. I don't know. *g* > PyKDE-3.8 (rc releases are at > http://www.sourceforge.net/projects/pykde) has a bunch of > application templates you can use to get started. Way cool. :D For us Gentoo users, I'll have to tweak the ebuild so that the examples, templates and all get installed under the doc directory rather than silently trashed, which is a bit dumb if you ask me. > Seems pretty difficult - my guess would be the most appropriate > route would be a tutorial/better docs/more example programs - > that's in the works, but takes a while to accomplish. That, and at least a basic knowledge of how to do things, and how not to. I suppose the right way to go about this would be to define a set of 'typical' apps (I'm thinking, for instance, small but potentially useful tools such as a 'universal' viewer based on KParts, a RSS newsticker panel applet, maybe a Konqueror sidebar plug-in showing info about the selected files based on their type, etc) and tutorialize their coding. Does that sound like a good idea? I mean, for the latter two, is extending KDE with Python stable enough that it can be done at all? I know there were threads this summer about problems related to panel applets... If at all possible, I think I'll give it a try once I know more about PyKDE. It really deserves to be better known! > The KDE > libs classref docs are pretty good, even if C++ oriented. You > find them at http://www.kde.org in the documentation section, > along with a lot of tutorial stuff. Yeah, I know, I've already started browsing the lot of them. Way interesting stuff, and very impressive. KDE is even better under the hood than it looks! -- S. ___ PyKDE mailing list[EMAIL PROTECTED] http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] ANN: new eric3 snapshot available
I heard Detlev Offenbach said: > This snapshot is available via > http://www.die-offenbachs.de/detlev/snapshots/eric-snapshot-20030914\ .tar.gz And here's the ebuild (it's exactly the same as for the last snapshot, only the name changes, and Portage makes the rest happen automatically -- so that you know how to Make Your Own when the next snapshot is released). :) -- S. DESCRIPTION="The eric3 Python IDE" IUSE="" MY_P="${PN}-snapshot-${PV##*.}" SRC_URI="http://www.die-offenbachs.de/detlev/snapshots/${MY_P}.tar.gz"; HOMEPAGE="http://www.die-offenbachs.de/detlev/eric3.html"; SLOT="0" LICENSE="GPL-2" KEYWORDS="x86" DEPEND="virtual/glibc sys-devel/libtool >=x11-libs/qt-3.0.4.1 >=dev-python/qscintilla-1.52 >=dev-lang/python-2.2.1 >=dev-python/sip-3.6 >=dev-python/PyQt-3.6-r1 !dev-python/bicyclerepair" src_install() { cd ${WORKDIR}/${MY_P} python install.py \ -b /usr/bin \ -i ${D} dodoc HISTORY LICENSE.GPL README eric/README-scripting.txt THANKS }
Re: [PyKDE] When should PYSIGNAL used ?
I heard Tony Cappellini said: > I was going through the pyQT tutorials when PYSIGNAL was used for the > first time in Tutorial 1-7. > Unfortunately the tutorial does not really explain what PYSIGNAL is > and when it is needed, and I don't see any references in PyQT Doc for > PYSIGNAL. Ah, maybe it was too well hidden in the doc... It's there: http://www.riverbankcomputing.co.uk/pyqt/docs/x381.html The gist of it is, if you're emitting a native Qt signal coded in C++, you'll be using SIGNAL. If you're emitting a signal you made yourself in Python, you'll be using PYSIGNAL. That's it. :) -- S. ___ PyKDE mailing list[EMAIL PROTECTED] http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
[PyKDE] QTextEdit and clickable links
Hello people, Is there any way to have clickable links in a QTextEdit? By peeking at Psi's sources, I determined that to make Qt check for links under the mouse pointer, you have to overload a linksEnabled() method to have it return TRUE. Only, this method is private in QTextEdit's code, and overloading it in Python doesn't seem to produce anything. (It is never called on my Python object). Is there any way to do it that I may not be aware of? Thanks in advance. If at all possible, I'd really like to avoid using QTextBrowser, because I will potentially be displaying a huge number of lines, and QTextBrowser would be way overkill. (If it worked in LogText mode, it would be even better!) -- S. ___ PyKDE mailing list[EMAIL PROTECTED] http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] QTextEdit and clickable links
I heard Sundance said: > Is there any way to do it that I may not be aware of? Okay, found it. Here's how I did, as a reference in case someone else has the same problem later on. :) The standard behavior of a QTextEdit's content widget (that you obtain with the viewport() method), is to have mouseTracking enabled. This is because QTextEdit is a specialisation of QScrollView. There is thus an event sent everytime the mouse cursor moves over the QTextEdit. This event can be caught by overloading contentsMouseMoveEvent(). In there, you get the current position of the mouse pointer, and see if there's a link at this position with QTextEdit's anchorAt method. This allows you to set the mouse cursor to a pointing hand when you're on a link. Be sure to set the mouse cursor for the viewport() and not the QTextEdit itself, since it's in the content, in the viewport(), that you want it to happen. And catching clicks is, likewise, a matter of overloading contentsMousePressEvent() and contentsMouseReleaseEvent(). Don't forget to forward the event to the parent class when you're done with it! That's it. I feared overloading a MouseMove event in Python would be awfully slow, but it seems to work fine. Aaand now, for bonus points, any idea about how to make links underlined only when the mouse pointer is over it? -- S. ___ PyKDE mailing list[EMAIL PROTECTED] http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] Notifying self on all emits _OR_ overriding default emit behavior
I heard Myddrin said: > For the sake of argument, let's say I need to know whenever an object > emits a signal. Well... I'm propably gonna say something stupid, but isn't the straightfoward way to do this, to actually connect the signal to a slot...? -- S. ___ PyKDE mailing list[EMAIL PROTECTED] http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] Notifying self on all emits _OR_ overriding default emit behavior
I heard Myddrin said: > If I could discover the slots at run time that would work, yes. > However PyQT doesn't expose this info (as far as I know) like the QT > library does.. Erm, so you mean you want to know what slots are going to get triggered by a given signal then...? Why do you want to do that exactly...? -- S. ___ PyKDE mailing list[EMAIL PROTECTED] http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] Notifying self on all emits _OR_ overriding default emit behavior
I heard Myddrin said: > No, I mispoke. Slots should be signals above. Oh! I see. :) > I would need to take a generic (or ones that inherit from say > MydWidget) object X and discover it's signals so I can subscribe to > them and then call the "webbrowser scripts" Well, I'm not really sure I grasp your problem there... Signals and slots are pretty much a compile-time information, as per Qt's design, and I'll venture to say that if you need to discover them at run-time there might be a design issue in your program maybe...? For instance, if you don't know before run-time what signals are likely to get emitted, and thus don't know their semantics, what exactly will you be doing with them? Connect them to slots that may end up being incompatible...? Darn, I really feel that I must be missing something here. Argh. If they are hand-made Python signals, maybe the most effective approach would be to register them at class level... I mean, what if MyWidget had something like a signalRegistry attribute that would contain the name of the PYSIGNALs that particular instance will want to emit? Or better yet, have a single signal that would emit its type as an argument, such as, say, webEvent("linkClicked", url), where "linkClicked" would be the type of the webEvent signal... Or something like that. I'm really having a hard time seeing the big picture about your approach, so I could be missing something. Good luck with the house hunting! -- S. ___ PyKDE mailing list[EMAIL PROTECTED] http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] Web article on wxWindows and PyQt
I heard Hans-Peter Jansen said: > Conclusion: beware from using qApp.quit(), or even sys.exit(0) > without thinking twice. There are almost always better ways to close > a PyQt application. Use them. This interests me. I've been trying to write a clean exception handler around the event loop, so that if an exception occurs in my end-user oriented application (darn, I speak like I had a tie...), a nice popup will warn the user, and then the app will quit cleanly, after saving its conf if at all possible. The quitting part is done with qApp.quit(). What should I do instead then? -- S. ___ PyKDE mailing list[EMAIL PROTECTED] http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] Web article on wxWindows and PyQt
I heard Hans-Peter Jansen said: > Just close()ing the main widget should do the job nicely, as long as > the exception doesn't occur in the ctor/dtor paths of the main > widget. Okay, danke schon! Erm... I happen to have another question... Exception handling while constructing the interface works fine, but I've got a problem with the event loop. While it is running, it'll drop all the exceptions silently after outputing the traceback to stderr. Is there any way to tell it NOT to brush exceptions under the carpet, so to speak? Or, alternatively, to install the exception handler *inside* the event loop rather than around it? > Needless to say, you cannot protect your app from crashes happened on > Qt level. Yeah, I know, but the point is mostly to keep users safe from bugs in MY code. :) > Comments? Yeah, your test app works perfectly here (PyQt and sip 3.8), no exceptions, no crash, etc. Is it normal? -- S. ___ PyKDE mailing list[EMAIL PROTECTED] http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
[PyKDE] Exceptions and event loop (was: Web article on wxWindows and PyQt)
I heard Hans-Peter Jansen said: > You could redirect stdout/stderr to an internal tee, which would > trigger a PYSIGNAL, which in turn triggers a corresponding dialog. I would *really* not want to go that way, if at all possible... I mean, having to parse a traceback for information, when an exception's traceback object already contains everything, would be a kludge unworthy of Python, frankly. :) > Again, how a about throwing things together to provide a minimum > example. I will try to help you as I can with the hairy parts ;) > [I'm somewhat time restricted atm] Here it goes. ---[ ExceptionHandler.py ]- from qt import * import sys import os.path NAME = "MySoftware" def bug(exception, traceback): line = traceback.tb_lineno filename = os.path.basename(traceback.tb_frame.f_code.co_filename) exception = str(exception) QMessageBox.critical(None, "Houston, we have a problem...", "Whoops. A critical error has occured. This is " + "most likely a bug in " + NAME + ". The error is:" + "%s" % exception + "It occured at line %d " % line + "of file %s." % filename + "" + NAME + " will now close.") mainwidget = qApp.mainWidget() if mainwidget: mainwidget.close() else: qApp.quit() class MyWidget(QTextEdit): def keyPressEvent(self, *args): raise Exception, "Hiya! I'm a bug inside the event loop!" app = QApplication(sys.argv) try: somewidget = MyWidget() app.setMainWidget(somewidget) somewidget.show() raise Exception, "Hiya, I'm a bug outside the event loop!" app.exec_loop() except Exception, err: dummy, exception, traceback = sys.exc_info() bug(exception, traceback) --- There. This demonstrates what I'm trying to do. When you run this code, it 'bugs correctly', so to speak -- the first exception gets caught, and the exception handler handles it, displays a nice friendly message, and when you click OK the app quits. I am very proud of this most professional-looking bug. Now, comment the raise clause that sits outside the event loop, run the program again, and when the QTextEdit appears, try to type something inside it. Since we override the KeyPress event handler with something that raises an exception, well, that exception will be raised, obviously: the traceback is displayed in the terminal, and... nothing else. The event loop just swallows the exception, and our exception handler is never notified that an exception occured. This is my problem, and it's fairly annoying. I'm pretty sure there exists a way to tell the PyQt event loop not to brush the exceptions under the carpet, since when an exception occurs you generally don't want to go on running like nothing happened, as the application state is now likely inconsistent, which might lead to data loss. Only, I have no idea how to tell that to the event loop. > Switch comments in close/closeEvent methods to expose qApp.quit() > and watch the different shut down paths. Oh. Right. Thanks. =D -- S. ___ PyKDE mailing list[EMAIL PROTECTED] http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] Notifying self on all emits _OR_ overriding default emit behavior
I heard Myddrin said: > Back to my original example. I webbrowser does _NOT_ know the events > (or signals or whatever) of every component that might get loaded > into it. Yet I can use Flash, Real Player, etc in both IE and > Netscape and receive events without the ie and netscape developers > having a priori knowledge of every component that might be loaded > inside it. Uh. As far as I know, (Netscape-style) plug-ins do not tell much at all to the browser -- they have their own event loop and handle their display themselves, with the browser none the wiser, except for a few predefined hooks such as "go to that URL". ActiveXs are slightly different, they work by exporting an interface over COM+, but unless I'm mistaken that interface has to derive from a 'known' interface for IE plug-ins -- so there's no 'new function' discovery. (Been long since I had to bang my head against them ActiveX though, so don't quote me on that.) You may want to peek at the KParts documentation, since it's readily available, topical for this list, *and* not bad at all. :) Here for the KPart Browser Extension: http://developer.kde.org/documentation/library/3.0-api/classref/kparts/ KParts__BrowserExtension.html You'll note that the browser checks for the presence of *known* slots to which it can connect its signals. An unknown slot won't be used. Which brings us back to the previously mentionned design issue. When you're loading some component into some framework, the framework must somehow know how to interoperate with the component. Typically the framework will call an initialization method on the component -- which implies that a method with that name MUST exist in the component -- and the component will return a list of capabilities, which can be as extensive as you'll want (for example the ability to register a menu entry in the framework...), but can't exceed the capabilities of the framework. Or the component can list its abilities in some attribute, in which case that attribute MUST exist in the component, so that the framework can go peek at it, etc. > Another example of what one might do (and I'm restricted here by an > NDA and can't tell you exactly what I'm planning on doing with it) So you need help on something, but can't tell us what. Wicked. 6,000 years of civilization, and then we invent the NDA. Go us. > > > > > Note that this would be a slot, not a signal. A signal doesn't contain code. > But I think in this case, I just answered my own question. I don't > need connect to all signals, just the ones that are in the file. Yep. In this case, the widget doesn't need the parent app in any way though, it can check for the mouse's position relatively to itself on its own. But I see what you're trying to do. You'll note that if 'mouseover' is a capability (slot) that the widget advertises, then the parent application will NEED to know what that 'mouseover' thing is in the first place, and that it should be triggered when the mouse is over the widget, or it won't be able to do anything with it on its own. Assuming you're working on, say, something like a tool to automatically make wizards based on an XML description file, for example, then you can simply create a dictionary attribute called 'mySlots' on the widget object when you create it from that .ui excerpt, and the parent app could simply check the content of this dictionary to know what capabilities the widget has to offer, and what methods are to be called to trigger each capability. Look at that KPart web page again, that's actually how it works. > Heck, since python can add methods at runtime, I could add them to > the object and do a straight connection rather than having an > observer class like I'd originally thought.. Yep. > Thanks, talking this out solved the problem, it was a design issue > after all. It often is. -- S. ___ PyKDE mailing list[EMAIL PROTECTED] http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] Exceptions and event loop (was: Web article on wxWindows and PyQt)
I heard Ulrich Berning said: > Have a look at sys.excepthook It works beautifully. Thank you so much, Ulrich! :) -- S. ___ PyKDE mailing list[EMAIL PROTECTED] http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] QComboTableItem problem
Heya people, Been trying to help Lionel there for a while, but I must admit his problem really puzzles me. Anyone more experienced than me care to give us a hand? Thankies. :) Using Qt 3.2.3, Python 2.3.2, SIP 3.8 and PyQt 3.8.1, the code listed in the parent message works just fine here. Apparently Lionel's problem is that on his computer the QComboTableItem is NOT painted (meaning that there's a standard empty cell displayed instead), unless it is the currently selected item in the QTable. Did I get it right, Lionel? I have strictly no clue about what could be causing this problem. Help. Thanks. =) -- S. ___ PyKDE mailing list[EMAIL PROTECTED] http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] Re: Welcome to the "PyKDE" mailing list
I heard David B Harris said: > Anybody know how on god's green earth eric3 looks so good in > http://www.die-offenbachs.de/detlev/eric3-screenshots.html ? It's the Plastik theme that ships with KDE 3.2. Looks really cool, alright. -- S. ___ PyKDE mailing list[EMAIL PROTECTED] http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] Direction of output
I heard [EMAIL PROTECTED] said: > I am interested in creating a free version of the windoze program > typeitin. It lets you generate an arbitrary number of buttoms, each > corresponding to an appropriate phrase. For example, you might have > To:, From:, password and so on. You focus on the target form, click > on the appropriate typeitin button and you have the desired text > transferred. Sounds interesting! Well, I don't think there would be any purely Qt-based way to do this, actually. What you need to do is 1) somehow get which window has the focus without displacing the focus (might be done with Qt), and 2) send X11 text input events to that window (and I have NO idea how to do that with Qt). If anyone knows how to do that, be it with Qt or maybe with some Python bindings to Xlib, it'd be an interesting challenge, at any rate. http://python-xlib.sourceforge.net/ looks like a good candidate. In particular, look at this: http://python-xlib.sourceforge.net/doc/html/python-xlib_14.html#SEC13 There could be another way to do a similar tool, though. When the button for email, name, phone, etc... is pressed, copy its content to the mouse clipboard (see the QClipboard documentation) so that the user can just click the middle mouse button in the destination form field to paste the appropriate text. Quite effective, if you ask me. Also note that a number of Linux tools (Konqueror, Mozilla...) do remember often used values in forms, so maybe your acquaintance's putative problem is really a non-issue? -- S. ___ PyKDE mailing list[EMAIL PROTECTED] http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] Looping over QLabels
I heard GuineaPig said: > In my application I have a QDialog with a lot of QLabels. From time > to time these labels need to be cleared (text set to ''). Is there a > way to iterate over the labels ? > I'm looking for something like this: > > for QLabel in self > QLabel.setText('') There is no direct way to do such a thing that I know of. However, you could easily code yourself a little function that would get your widget's subwidgets (with the .children() method) and filter out the non-QLabel ones: def getChildrenByType(obj, type): children = obj.children() isTypeSuitable = lambda child: child.isA(type) return filter(isTypeSuitable, children) for child in getChildrenByType(self, "QLabel"): child.setText('') -- S. ___ PyKDE mailing list[EMAIL PROTECTED] http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] Eric3 First impressions and questions
I heard Phil Thompson said: > You must take the same steps as you would if developing an > application for external users. If your users have access to the Qt > API then they will be considered developers and each will need a > license. If not, then you only need one for the person "developing" > your eric package. Hmm, and when you're done, I think maybe you'll want to put the Eric3 Windows binary up somewhere, along with a large "Donations!" button to try to recoup your loss. It's a real pity that the interpreted way Python works would force simple users to get a developper license... But maybe there are still ways to do with it. -- S. ___ PyKDE mailing list[EMAIL PROTECTED] http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] ANN: Wiki for PyQt/PyKDE
I heard Torsten Marek said: > as the title suggests, we have a new wiki only for PyQt and PyKDE + > related development. This is excellent! Thank you loads! :) Could there be a link to the Wiki from the KDE web site? Also, will you be posting a news item about it on the Dot (which I believe would be a great idea)? Thanks again! :) -- S. ___ PyKDE mailing list[EMAIL PROTECTED] http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
[PyKDE] Custom QScrollBar'ed widgets
Greetings, I would like to attach scrollbars to a custom widget, and I'm not sure how to go about it. What is the simplest/cleanest way of informing the QToolBar of the custom widget's viewport size change (when text is appended, for instance), and to sync the scrollbar with the viewport's position, both ways? I'll go for cleanest over simplest, if it comes to a choice between the two. :) -- S. ___ PyKDE mailing list[EMAIL PROTECTED] http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] Custom QScrollBar'ed widgets
I heard Gordon Tyler said: > Have a look at QScrollView: > http://doc.trolltech.com/3.3/qscrollview.html > > The Detailed Description section should give you the information you > need for scrolling custom widgets. Thank you, but this won't do. I'd need to attach the scrollbar to a custom widget, *not all* of which will scroll, hence making QScrollView useless for this case. Basically, instead of a viewport, the widget would have a QVBox containing several subwidgets, the actual viewport being only one of those. I don't know if overriding the viewport can be done directly, so I've tried going for another approach, where I manually attach an independant QScrollBar to my custom widget. But I still need to know how to sync the scrollbar to the widget's viewport. :) Thanks, -- S. ___ PyKDE mailing list[EMAIL PROTECTED] http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] Custom QScrollBar'ed widgets
I heard Gordon Tyler said: > So these other subwidgets stay still while this one other widget > needs to scroll? I feel cross-eyed already ;) Yes. I'm trying to see how cleanly I could implement that nifty feature in KMuddy, split-screen on scrollback, that splits the viewport when the users scrolls back to let him keep an eye on what is going on in the game while he searches his history. Their implementation works, but seems a bit kludgy -- for instance, when it is shown, the bottom text area's frame covers the edge of the scrollbar. So I'm trying to come up with something cleaner. > So why don't you just wrap this one subwidget in a scrollview? Because the bottom text area will or will not be shown depending on whether the user is currently scrolling back or not. The scrollbar must thus cover /both/ text areas. If you make it cover only the upper text area, the one that is scrolling back, then that scrollbar will be suddenly resized under the user's pointer when the bottom text area is shown. Not good. > If your scrolling subwidget has a custom paintEvent handler, then > maybe you can tie the scrollbar's value to a y-offset that's applied > to all the drawing operations in the paintEvent handler? Could be an idea. Maybe I'll also read the source code of Kompare, which does some real nifty scrollbar magic. -- S. ___ PyKDE mailing list[EMAIL PROTECTED] http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
[PyKDE] Connect syntax.
Hello, It occured to me, while I was code-doodling today, that as it currently stands, the connect syntax in Python is just a tiny little bit more awkward than necessary. See: class MyNiftyLittleWidget(QSomeWidget): def __init__(self, otherWidget): # ... # Blah # ... self.connect(self, PYSIGNAL("kissed()"), otherWidget.blush)) self.connect(self ...) is just a little bit too awkward to fit nicely with either Python's cleanliness or Qt's lean efficiency. Makes it a fairly uncomfortable spot to be in when someone tries to advertise PyGTK as 'cleaner' to your boss. For instance. Could it be possible to make connect a global function of the qt Python module? Please? Like, "connect = QObject.connect" just at the end of the wrapper? This would be such a lot more logical and smoother. Allowing connect to work as an *instance* method would also be WAY cool: self.myButton.connect(SIGNAL("clicked()"), self.doSomething) but it would likely much harder to implement -- although I certainly don't put it above Phil's abilities, please don't get me wrong. What do you think? -- S., hopeful ___ PyKDE mailing list[EMAIL PROTECTED] http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] Connect syntax.
I heard Phil Thompson said: > I have a policy of not (if at all possible) changing or "enhancing" > the API. C++ Qt: SomeWidget::SomeWidget () { // ... connect (this, SIGNAL("whatever()"),// <-- look! otherWidget, SLOT("blah()")); // ... } Current PyQt: class SomeWidget(QWidget): def __init__(self): # ... SELF.connect (self, SIGNAL("whatever()"), # <-- look! otherWidget, SLOT("blah()")) # ... Keeping the same API as C++ Qt is in fact what I was suggesting. :) The Qt API is /damn/ good. In this case as in others, I'd rather see the Qt API adapted faithfully than bent slightly under one of Python's idiosyncrasies. Point taken about making connect an instance method, however. -- S. ___ PyKDE mailing list[EMAIL PROTECTED] http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] Connect syntax.
I heard David Boddie said: > Can't you achieve this by rebinding connect like you suggested > before? Yep, in fact that's what I'm planning to do in a small homemade wrapper around PyQt. > Did I miss that part of the discussion? :-/ Oh, it was just an idea about allowing this syntax: someButton.connect(SIGNAL("clicked()"), otherObject.someMethod) IE, making the first argument implicit when connect() is used as an instance method. Which seems a LOT more logical and pythonic. However, as Phil points out, it doesn't respect the Qt API. This can be achieved by fiddling with QObject.connect at wrapper level. I don't know how much of a performance impact it has, however. -- S. ___ PyKDE mailing list[EMAIL PROTECTED] http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] Connect syntax.
I heard Bryan O'Sullivan said: > What's wrong with not respecting the Qt API? The Principle of Least Surprise, I suppose. I'll venture that Phil's clients are in good part people who already know Qt and are moving to Python. It would not be very good marketing to surprise them with significant API changes, I suppose. Also, I like your wrapper script. Can I use it in my own code, and what license does it come under? -- S. ___ PyKDE mailing list[EMAIL PROTECTED] http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] eric3 anti-aliasing problem (!?)
I heard Solly Brown said: > In fact, the fonts in the > menu-bar, tabs, and dialogs in eric3 are perfectly ok too... for some > reason it's just the main text editing window/widget in eric3 which > seems unable to produce anti-aliased text. Hello Solly! Okay, could you maybe upload a screenshot somewhere to give us a better idea of the issue? Who knows, maybe it's just one silly detail that we overlooked. :) Fonts are Just Fine(c) here, so the problem might be on your end. I don't use monospace fonts either, but everything is stll smooth and antialiased and a delight to the eye. Yes it is. If I can venture a blind guess, your problem looks like some font substitution resolving into a bitmap font, which thus doesn't scale and cannot be antialiased. (Bitmap fonts should die. Once I tried to remove them all, leaving only the pure, pristine Type1 and FreeType fonts. XFree refused to start. I hate XFree.) In short... Go into Eric3's preferences and set some known-to-work font as the default. Courier New remains my fav' monospace font; for regular fonts, I use either good old faithful Arial, or Nimbus Sans L. If you're short on vectorial fonts, don't be afraid to install those from Microsoft, they're pretty darn fine. And they don't crash. You can get them off http://corefonts.sourceforge.net/. The Nimbus fonts come with Ghostscript. There, this SHOULD help. I hope. Bye, -- S. ___ PyKDE mailing list[EMAIL PROTECTED] http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
[PyKDE] The tablet event, it works not!
Hello people, I've been playing around with tabletEvents, and they just plain don't work. See the attached script: ---[ tabletevents.py ]- import sys from qt import * class TabletWidget(QLabel): def __init__(self, parent=None, text="Please move and click\nthe pointer here!"): QLabel.__init__(self, parent) self.setText(text) self.setAlignment(Qt.AlignHCenter|Qt.AlignVCenter) self.setMinimumSize(QSize(320, 200)) self.setMouseTracking(True) # It doesn't change a thing if I set mouse tracking to off, note. def tabletEvent(self, e): deviceType = e.device() deviceTypeName = { e.NoDevice: "None/Unknown", e.Puck: "Puck", e.Stylus: "Stylus", e.Eraser: "Eraser" } [deviceType] pressure = e.pressure() idType, idSerial=e.uniqueId() x = e.x() y = e.y() print "Device %d:%d (%s) X:%d Y:%d Pr:%d" % \ (idType, idSerial, deviceTypeName, x, y, pressure) e.ignore() # It doesn't change a thing if I accept() the event instead, note. if __name__ == "__main__": app=QApplication(sys.argv) widget = TabletWidget() app.setMainWidget(widget) widget.show() app.exec_loop() --- This is with Qt 3.3.3 and PyQt 3.12. Yes, Qt has been compiled with tablet supported enabled, I've doublechecked. Anyone has any idea what I'm doing wrong? Thanks. :) -- S. ___ PyKDE mailing list[EMAIL PROTECTED] http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] The tablet event, it works not!
> This is with Qt 3.3.3 and PyQt 3.12. > Yes, Qt has been compiled with tablet supported enabled, I've > doublechecked. > > Anyone has any idea what I'm doing wrong? Still no taker...? -- S. ___ PyKDE mailing list[EMAIL PROTECTED] http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] The tablet event, it works not!
I heard Kaleb Pederson said: > Is your event handler being called at all? Nope, it isn't. > If not, it sounds like your kernel and X aren't configured correctly. I doublechecked that they are, don't worry. :) And xinput devices work fine in Gimp. I suspect the problem resides in the event not being emitted when I assumed it would be. Maybe a tablet equivalent of QWidget.setMouseTracking(). But I've not found anything of that kind so far... -- S. ___ PyKDE mailing list[EMAIL PROTECTED] http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] The tablet event, it works not!
I heard Kaleb Pederson said: > I do, sorry :) Even though I don't have the wacom module loading on > mine, I can use my tablet in Gimp -- I just can't use the tablet > specific items. I can. All of them are recognized alright: pointer, stylus, eraser. Additionally, the pointer is in relative mode and the others in absolute mode -- which is not the case when X is using the tablet with a -mouse- driver. I really, really triplechecked this, you know. :) > Nothing special is required, just the catching of the tabletEvent > signal. > > I'll let you know what I find. Thanks. I'm beginning to suspect a Qt bug. I ported my example to C++, and it doesn't work either. I re-re-rechecked my Qt compilation log and tablet support is definitely turned on. Could it be that Qt didn't compile tablet support even though the configure script claims it did? If so, how can I check? -- S. ___ PyKDE mailing list[EMAIL PROTECTED] http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] The tablet event, it works not!
I heard Kaleb Pederson said: > My new kernel works. Your program worked just fine with my Tablet as > did my old test program (I would have given it to you as well, but I > wasn't sure what state I had left it in). I'm using sip 4.1.1, PyQt > 3.13 and Qt 3.3.3. There must be something else awry :( Raahr! *bites into various things* Okay, so. I'm confused. I'm running Qt 3.3.3 and PyQt 3.12 with SIP 4.0.1. Tablet drivers are linuxwacom 0.6.3 on kernel Andrew Morton/2.6.7 and X.Org 6.8. I'll update my packages to the same versions you use, and get back to you. In the meanwhile, please find attached the C++ test code. 'qmake -project && qmake && make' to compile. Thank you very much for your kind help. I was starting to grow desperate. -- S. #include #include #include #include class QSize; class TabletWidget: public QLabel { public: TabletWidget(QWidget *parent=0) : QLabel(parent) { setText("Please move and click\nthe pointer here!"); setAlignment(AlignHCenter|AlignVCenter); setMinimumSize(QSize(320, 200)); setMouseTracking(true); } protected: void tabletEvent(QTabletEvent *e) { QString deviceTypeName; switch (e->device()) { case QTabletEvent::Puck: deviceTypeName = "Puck"; break; case QTabletEvent::Eraser: deviceTypeName = "Eraser"; break; case QTabletEvent::Stylus: deviceTypeName = "Stylus"; break; default: deviceTypeName = "None/Unknown"; } cout << "Device:" << deviceTypeName << " Pr:" << e->pressure() << " X:" << e->x() << " Y:" << e->y() << endl; e->ignore(); } }; int main(int argc, char *argv[]) { QApplication app(argc, argv); TabletWidget widget; app.setMainWidget(&widget); widget.show(); return app.exec(); } ___ PyKDE mailing list[EMAIL PROTECTED] http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] The tablet event, it works not!
I heard Kaleb Pederson said: > Ok. I would probably only look at Qt as it sounds like it's the > culprit. Could Python or your C++ program have linked to a different > version of Qt that didn't have tablet support? Package management makes it very, very unlikely. I've doublechecked, to be certain, and it's indeed the correct version of Qt that is being used. May I ask which Wacom drivers you're using, just out of curiosity? It might be that those I use break Qt support, for some weird reason. > I'm sure that as soon > as you get Qt working, you'll be able to get it working on Python. Okay, I'll work on that, then. > Your C++ version worked fine as well. Grah. At least I need not fear for my coding sK33lZ. Thank you loads and loads for your time, Kaleb. :) -- S. ___ PyKDE mailing list[EMAIL PROTECTED] http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] big Text in pyqt
I heard Axel Mittendorf said: > Hi, what is the most efficient way to display a big text in a pyqt > app? Did you try to set the QTextEdit widget in LogText mode? t=QTextEdit() t.setTextFormat(QTextEdit.LogText) You may also want to turn undo/redo off: t.setUndoRedoEnabled(False) How much better is the memory consumption with this? -- S. ___ PyKDE mailing list[EMAIL PROTECTED] http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] Help with simple clipboard examples
I heard Stephen Boulet said: > I'd like to get and set the X-window clipboard for some short > scripts, but I'm not doing it quite right. Can someone help me along? Okay, it seems to work here (I just did the imports outside the function calls, since doing it inside functions is -bad- practice). What is your problem exactly? Also, I discovered that the QClipboard.setText() call freezes Klipper, which in turns 'freezes' X (mouse and keyboard events are not processed); I have to switch to a console and kill Klipper. Does anybody have any idea what's up? -- S. ___ PyKDE mailing list[EMAIL PROTECTED] http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] Help with simple clipboard examples
I heard Stephen Boulet said: > I just want to have a module to use under linux that would let me get > and set the clipboard Your previously posted code should work fine for this purpose. Just take the imports out of the functions. -- S. ___ PyKDE mailing list[EMAIL PROTECTED] http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] Using custom components and Qt Designer with QWidgetFactory in PyQt
I heard Truls A. Tangstad said: > Maybe a possible solution might be to create a QWidgetFactory > replacement that runtime uses pyuic and execs the result... if > nothing else this allows custom components specified in the Designer > to be created correctly since pyuic uses code from the Comments field > which QWidgetFactory ignores. You know, what would REALLY kick butt would be a way to import .ui files directly. Like: from MyWidgetUIFile import MyWidget That's how the Python bindings for the ORBit CORBA implementation works. You can import IDL files directly. This really, /really/ makes a difference in development cleanliness and flexibility. Anyone has any idea how to do that? -- S. ___ PyKDE mailing list[EMAIL PROTECTED] http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] Static member functions
I heard Hihn, Jason said: > How can I do this in python? It may be I'm not getting your question, but... What's the problem exactly? You can have global objects (which includes functions) all you want, really. Example: ---[ globalstuff.py ]-- data = None --- ---[ A.py ] import globalstuff def functionA(): globalstuff.data = 42 --- ---[ B.py ] import globalstuff def functionB(): print "The global data contains:", globalstuff.data --- ---[ main.py ]- import globalstuff from A import functionA from B import functionB # Set the global bit of data with functionA() from module A: functionA() # Print the global bit of data with functionB() from module B: functionB() # Set the global bit of data ourselves: globalstuff.data = "Nobody expects the Spanish Inquisition!" # Then print it with functionB() from module B: functionB() print "See, Jason? I don't understand what your problem is, exactly." --- Does this answer your question? -- S. ___ PyKDE mailing list[EMAIL PROTECTED] http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] Static member functions
I heard Hihn, Jason said: > Ok, my problem is that I want to provide some function that is called > by the widget that generates the signal. I'm not sure I fully get your problem, I'm afraid (I'm a bit slow like that), but: http://doc.trolltech.com/qq/qq10-signalmapper.html Would this help? -- S. ___ PyKDE mailing list[EMAIL PROTECTED] http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] Re: QString in PyQt4 - Request for Comments
I heard Michael Thompson said: > No, the goal should be to work away at making QString interacted with > str/unicode more invisibly/naturally - where possible. Yeah, I'd sort of second that. The 'pythonic' way is pretty much duck typing, I think, in this sort of situation. How difficult would it be to wrap QString in a class that would also implement all that str (or unicode) does? Possibly by wrapping QString methods, in fact, for performance. That way, you get something that looks like a str, acts like a str, smells like a str, and really is a QString under the hood. Grooviness. That'd make me Happy(tm). (And just so I know, how far up my butt have I stuck my head there?) Ta ta, -- S. ___ PyKDE mailing listPyKDE@mats.imk.fraunhofer.de http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] QString in PyQt4 - Request for Comments
I heard Mike Tammerman said: > I don't know how difficult or feasible it is, but I would suggest > using macros, so people can choose whether to use QString or python > str while compiling pyqt. Please, no! If we do that, we'll never be able to release a PyQt program and be certain it'll work on the user's machine and whatever incompatible variant of PyQt they compiled. -- S. ___ PyKDE mailing listPyKDE@mats.imk.fraunhofer.de http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] unicode two-way conversion
I heard Sebastian Kügler said: > So what I basically need is a two-way conversion between unicode > strings and ascii (or at least something that is easily usable > together with psycopg and postgres' character fields. Hello Sebastian, You most probably want to read this: http://www.joelonsoftware.com/articles/Unicode.html Seriously. It's not a very long read, and you'll never have a problem with Unicode ever again. And you'll get to appreciate how nice Python's Unicode support is, too. You'll see. It saved my day many times already. :) Ta ta, -- S. ___ PyKDE mailing listPyKDE@mats.imk.fraunhofer.de http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] PyQt4 Status Update
I heard Phil Thompson said: > I hope to have the remaining modules complete by the end of the year. > This might depend on the release of Qt 4.1. pyuic and QScintilla may > take a little longer. > > Testing so far is virtually non-existant. Hello Phil, Do you think it would be possible to make intermediate releases with partial functionality? Like, by first implementing QMainWindow and a small set of the most common widgets, and adding the others prerelease after prerelease? That way, those of us waiting for PyQt4 to start new projects could slowly get to work at your own rhythm, while already providing you with the testing you need. Does that make sense? Or am I talking out of my rear end for organizational or technical reasons? Thanks, -- S. ___ PyKDE mailing listPyKDE@mats.imk.fraunhofer.de http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] What little detail am I missing?
I heard Tina Isaksen said: > Well, I have been doing that for quite a while actually and can > pretty much do what I want. And maybe that is the problem... I do > stuff 'the wrong way'... Hello Tina, I'd say there are two important things there: 1) Figuring out just what you're doing wrong; 2) Figuring out WHY it's wrong. Nothing will get you there but practice and orthogonal thinking. In particular, once you've got the Python syntax down, you might want to look into doing the sort of exercises that the Programming Kata site suggests: http://blogs.pragprog.com/cgi-bin/pragdave.cgi/Practices/Kata It comes with practice. Don't despair, and by all means, whenever you find yourself wondering how you could go about implementing something (command line file finder, automated mailed reminders, network prober... anything!), sit at your keyboard and do it. That's how you improve! -- S. ___ PyKDE mailing listPyKDE@mats.imk.fraunhofer.de http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] QtCore.Qt and QtGui.Qt
On Thu, Mar 02, 2006 at 09:46:03AM +, Phil Thompson wrote: > The short answer is that the Python objects are placed in the module > corresponding to the C++ library in which they are implemented. Hmm, meaning that this: ---[ Code snippet ] from PyQt4.QtCore import Qt as Qt1 from PyQt4.QtGui import Qt as Qt2 if Qt1 is Qt2: print "The Force is strong with that one." else: print "Wow, we might be having a structural problem of sorts there..." --- ... would actually not print out a cheap Star Wars statement regarding PyQt? Shouldn't the Qt namespace be common across all the modules? I understand that's the case with the C++ version, isn't it? With kind regards, -- S. ___ PyKDE mailing listPyKDE@mats.imk.fraunhofer.de http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] QtCore.Qt and QtGui.Qt
On Thu, Mar 02, 2006 at 10:41:45AM +, Phil Thompson wrote: > A C++ namespace doesn't have an implementation, it just contributes to > name mangling. In Python they have to be implemented by something so > there is no direct comparison. Point! Although I feel Giovanni does have a point as well. Having DIFFERENT Qt namespaces lying around is super ungood. Recipe for pain, that. I think this is one of those cases where we should polish things into submission manually if need there. I can see several potential approaches. 1) Having the Qt namespace as an external module. Modules are good. Modules are designed precisely for the purpose of providing namespaces. However, the current PyQt implementation might not make that feasible. 2) Updating QtCore.Qt's __dict__ in the other modules instead of creating a new Qt there. You know, from QtCore import Qt Qt.__dict__.update(my_own_Qt_namespace) ... inside each module other than QtCore. Just an idea anyway. What do you guys think? -- S. ___ PyKDE mailing listPyKDE@mats.imk.fraunhofer.de http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] QtCore.Qt and QtGui.Qt
Giovanni Bajo wrote: > This would be *very* confusing and very implicit. I'm -1000 on this. Actually, it's more than merely implicit: it's Plain Freaking Magic. And magic is dangerous. I agree that making the Qt namespace a module of its own would be one darn lot better. What I don't know is whether it's possible. Phil? -- S. ___ PyKDE mailing listPyKDE@mats.imk.fraunhofer.de http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] sip searchs incorrectly for qmail specs
On Thu, Mar 02, 2006 at 12:33:23PM +0100, Andreas Pakulat wrote: > Right and that was caused by you not setting the QTDIR variable > properly. QTDIR should point to /usr/share/qt not /usr. Actually, I understand that Qt 4 doesn't use $QTDIR anymore, so I imagine that sooner or later the PyQt build process will have to do without. It doesn't have to be too complicated, either. A few command line options to set the include path, the lib path and the bin path manually, without changing anything else, should suffice in order to please The People. A lot of distributions try to install Qt cleanly within their own directory structure, and forcing them to set a bunch of symbolic links in some directory in order to emulate Qt's default one-dir-for-all structure might not make them exceedingly happy with us, I don't know. Just a thought, anyway. -- S. ___ PyKDE mailing listPyKDE@mats.imk.fraunhofer.de http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] QtCore.Qt and QtGui.Qt
On Thu, Mar 02, 2006 at 02:01:35PM +, Phil Thompson wrote: > As I said in another reply - I don't see the difference. Whether it's > PyQt4.Qt rather than PyQt4.QtCore.Qt, the magic still has to happen > when you import QtGui. Well, I think the idea is that the Qt namespace would contain everything it needs to, from all the PyQt modules, right from the start. I.e. even if you only import QtCore, the Qt namespace would contain WhiteSpaceMode and all. Always the same, no changes no matter what you import and don't import. But as said, I understand that this may not be easily feasible within the SIP/PyQt architecture (because, mind, I don't know HOW the namespace is implemented there to start with. There are a lot of people here who Know Their Shit like there's no tomorrow, but I'm not one of them). -- S. ___ PyKDE mailing listPyKDE@mats.imk.fraunhofer.de http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] QtCore.Qt and QtGui.Qt
On Thu, Mar 02, 2006 at 02:58:18PM +, Phil Thompson wrote: > What you describe can be implemented, but it means that the Qt module > must be linked against the Core and Gui Qt libraries. Oookay, you've lost me there. I thought that, with the exception of convertFromPlainText(), escape() and mightBeRichText() (which you can implement as part of QtGui all you want, since they're defined in QTextDocument anyway), the Qt namespace only contained enums? What am I missing here? Does the way PyQt works absolutely requires that the enums would be the exact C++ type that the library uses, rather than, you know, just ints...? Thanks, -- S. ___ PyKDE mailing listPyKDE@mats.imk.fraunhofer.de http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] QtCore.Qt and QtGui.Qt
On Thu, Mar 02, 2006 at 03:15:45PM +, Phil Thompson wrote: > I like it - except I would use "Qt" rather than "qt". In fact I > really, really like it. Ditto! Giovanni, say: would that also remove the drawback from your awesome static PyQt module project? I looked into the issue of distributing easy-to-install binaries for Windows, and couldn't get around the problem of PyQt's size. So I'm really enthusiastic about your project. Do you intend to distribute pre-made PYDs, by the way? Thanks, -- S. ___ PyKDE mailing listPyKDE@mats.imk.fraunhofer.de http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyQt] Re: PyQt4 and Python 3.0
Henrik Pauli wrote: >> And we could have just as many Viper versions as we'd damn well >> please within any given Python and Qt release timeframe -- we'd >> simply import from Viper2, Viper3... rather than Viper. > > Hmmm, true that, but since Py2 and Py3 are completely different > matters (as far as I understand), thus have completely separate module > bases, it could be just Viper in both, without clashing whatsoever. Hi, Maybe I didn't express myself clearly, but in my thinking, 'Viper' versions and Python versions would be orthogonal, so Viper2, Viper3... would be referring to the respective versions of the bindings, NOT the versions of Python. The whole /point/ would be to be independant of the Python versioning scheme. :) In other words, a given version of 'Viper' could conceivably be designed to be able to build against both Python 2 and Python 3, although of course a later version would eventually drop support for Python 2. That's what drove the organisation of the scheme I posted about: it allows smooth transitioning between versions of Python as well as between versions of Qt -- without making it mandatory, either, because supporting several Python versions with one build is bound to be a lot of work that Phil may not want to undertake. Also, Phil wrote: > Strictly speaking the '4' refers to PyQt and not Qt, but this is one > case where it's better if I agree with everybody else rather than > insist on my view of the world. Oh, you are absolutely correct, of course. The only point of giving the product a whole new name like 'Viper' (or whatever the heck, really) would be to make /your/ view, which I happen to agree with, unambiguous to everybody else. > The 'Qt' part of the name is ok, it's the version number that's the > problem. "Viper" can be "PyQt". You are of course entirely right. To complement on the above, the only reason why I put this notion forward is that 'import Viper5.Qt4' is perhaps one little bit less confusing than 'import PyQt5.Qt4', in, well, the everybody-else's-worldview you were referring to. (Plus the numbering of Viper or whatever could conceivably start over at 1 instead of picking up that of PyQt, I really don't care either way.) You also suggest the 'from PyQt4v2 import QtCore' and 'from PyQt4.v2 import QtCore' schemes, in which, if I'm not mistaken, the '4' in PyQt4 would now start referring to the Qt version, is that correct? If so, the scheme would be functionally equivalent to what I suggested, minus the possibility to support different Qt versions within one PyQt version, which is really no big deal AFAIC. So the only issues left would then be possible ambiguities with the current PyQt4 module's organisation, and, well, aesthetics. On that note, please don't go with 'from PyQt4 import QtCore2'. :) If the module's name is QtCore in Qt, it should be QtCore in the bindings as well. Plus I can already foresee namespace clashes with that scheme. Thanks, -- S. ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
Re: [PyQt] Re: PyQt4 and Python 3.0
Phil Thompson wrote: > Regarding numbering, my current thinking is... > > from PyQt4 import QtCore2, QtGui2 Hi all, I would like to go out on a limb and share a few thoughts that came to me with you guys. Essentially, the name of PyQt4 seems to carry some embedded confusion, in particular about what exactly the '4' applies to -- the whole PyQt, or only the Qt part. That's not a bad thing in itself; for long, it has been applying to both, so the double meaning is fitting. However, if the versioning of PyQt is going to become dissociated from that of Qt, perhaps the naming scheme itself should reflect it. It's not necessary to change the name of PyQt itself, although perhaps that might be envisioned (anyone knows the name of a species of, err, cute pythons?), but mostly it'd be about getting the 'Qt' part out of the actual name so we could do something like: from Viper import Qt4 or from Viper.Qt3 import qt, qttable or from Viper.Qt4.QtGui import * ... and so on. ('Viper' fails at both cute and python, I know. I suck with names, but this is just an example, so please bear with me.) In the above scheme, Viper would be a common namespace with three purposes: - Dissociating bindings versions from Qt versions (which is the main issue that is being discussed in this here thread); - Raising a friendly, explanatory exception when trying to access a Qt version for which no bindings are installed; - Raising an exception, I guess, if the user tries to import the bindings for another version of Qt when there's already a different one loaded (assuming that is even necessary). I don't know how well SIP supports buildings against different versions of Qt, but I suppose there is nothing to keep us from having one different build for each Qt version anyway, exactly the way it currently works -- only they'd all be installed under a common Viper namespace. I suppose such distributions as Debian would want to split the packaging into viper-qt3, viper-qt4, and viper-common, which is entirely fine with me. With this neat module organisation in place, we could then ship the bindings as "Viper x.y for Python 2.x" or "Viper x.y for Python 3" without excessive confusion. And we could have just as many Viper versions as we'd damn well please within any given Python and Qt release timeframe -- we'd simply import from Viper2, Viper3... rather than Viper. Thoughts? -- S. ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
[PyQt] Re: Python frame never dies on application errors
Fabio Menegazzo wrote: > Consider a widget in the display. When an exception happens the Python > frame never dies. Am I doing something wrong? Hi Fabio, In your example, your exception occurs while the frame for SlotRaiseError() is still on the stack. The traceback thus keeps a pointer to that frame, which is why the stub variable's refcount doesn't reach 0. You are trying to use sys.exc_clear(), but that function makes strictly no promise as to what variables are going to get cleared, or when (see http://effbot.org/pyref/sys.exc_clear.htm). In particular, it doesn't clear the reference to the last traceback that is available in the sys module. Contrast the example: ---[ Example ]- import sys from PyQt4 import Qt class Stub: def __init__( s ): print "I'm a stub instance and I was just created!" def __del__( s ): print "Whoops, my refcount is zero and now I die!" class TestClass: def causeHavoc( s ): stub = Stub() raise Exception( "Whoops, an error occurred!" ) def clearTraceback( s ): print "Deleting last traceback..." sys.last_traceback = None ## HERE! def start( s ): app = Qt.QApplication( sys.argv ) Qt.QTimer.singleShot( 1000, s.causeHavoc ) Qt.QTimer.singleShot( 2000, s.clearTraceback ) Qt.QTimer.singleShot( 3000, app.quit ) app.exec_() t = TestClass() t.start() --- In this example, the stub variable is correctly collected when the reference to the traceback is deleted. In short: business as usual. Python works fine, it just keeps a reference to the last traceback that you didn't know about. :) Hope this helps, -- S. ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
Re: [PyQt] PyQt4.Qtcore defines 'hex'
Adeodato Simó wrote: >If you see in the middle of a program hex_(foo), you may wonder where >that came from, whereas qhex(foo) is going to be rather obvious. Greetings all, Might I humbly second this motion? I do understand the usual reservations about star-imports (being the kind of guy that often gets to debug other people's work...), but I also do appreciate the relative ease of getting away with it in PyQt's case, thanks to the prevalence of the Q prefix in its class names and its relative absence of module-level functions. With this in mind, using the same prefix for the three problematic functions makes good sense to me. Are there reservations about this approach that I may not be aware of? Ta, -- S. ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
Re: [PyQt] Dialogue box with hyperlink
Geert Vancompernolle wrote: > Has anyone somewhere an example code of a small dialogue box which > contains a hyperlink to a web site? http://spyrit.svn.sourceforge.net/viewvc/spyrit/trunk/AboutDialog.py?revision=187&view=markup Basically, you use a QLabel that contains your link in HTML, and don't forget to setOpenExternalLinks( True ) on that label. Links are then opened when clicked with the user's default Web browser. That's all! -- S. ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
Re: [PyQt] LGPL license.
Giovanni Bajo wrote: > You're basically restating your previous point, without debating mine. > The language choice affects companies much more than £350 / > programmer. Hi Giovanni, hi Phil, hi everybody, Giovanni, I'm... a bit uncomfortable writing this because I generally agree with you, and don't want to come across as confrontational, but I think there is still something worth pointing out that I feel you left out from your reasoning. In my (limited) experience, a major parameter in language choice in medium- to large-size companies is developer availability. Languages for which developers are easier to find get a significant advantage (hence the commercial success of PHP, for instance). >From this, it follows that fostering a broad ecosystem of developers does help your language in the end, so those small-scales developers for whom £350 is a big deal do actually matter to you, indirectly. Actually, I think it goes even more so for those developers that only start dabbling for whom the option of eventually relicensing their product and selling it might make a difference. So, no LGPL for PyQt might mean less small-scale developers picking up Python for their Qt development, which in turn means less Python developers out there as a whole and a lesser chance for bigger companies to eventually settle for Python as their chosen tech. Or something to that extent anyway. Hard to tell how much weight that reasoning actually carries in practice. Not too much, I hope (but I dare not be optimistic). Sill, that's why I, for one, *hope* PyQt will eventually end up LGPL in a commercially sustainable manner (the best option being sponsorship from Nokia... one can dream!). But that's only a hope, one I barely dare voice at that, and is no way a demand. :) Bye, -- S. ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
Re: [PyQt] Problems with QSystemTrayIcon
Philippe Fremy wrote: > I am having problem to get QSystemTrayIcon to work. I am running on > windows XP and I never see any notification messages. > > My setup: windows XP, PyQt 4.3.3, python 2.5 Hi Philippe, Your code looks fine to me, and works fine here on Linux (Qt 4.4.3, PyQt 4.4.4). According to the Qt documentation, the .showMessage() method may fail to display its message depending on the system's configuration (this seems to be irrespective of what .supportsMessages() tells you -- because message are /supported/ doesn't mean they /will/ necessarily be displayed). So perhaps you may want to start looking in that direction. Otherwise, well, if I had this problem, I think I'd solve it by going a different route entirely, since .showMessage() is, as per the documentation, officially unreliable. Do you think you could, for instance, animate the tray icon when there is a pending message, and then open a passive pop-up when the user clicks the icon? A bit more work, I know, but such is the price of reliability in the face of uncooperative operating system. HTH, -- S. ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
[PyQt] QtWebKit to PDF rendering
Dominic Jacobssen wrote: > Anyway, I've attached my efforts, and I'd greatly appreciate any > guidance or prodding in the right direction. Hi Dominic, hi all, Attached herein is a version that works by sizing the PDF page correctly. (Also the URL and destination file are command line arguments, and no longer hardcoded, for simplicity.) So it's still a one page PDF, but it doesn't cut off the contents anymore. Otherwise I couldn't find hooks for automated pagination. It may be you will have to write those yourself, which shouldn't be horribly complicated. Basically, I think: create a QRegion the size of your PDF page; render the main Web frame *clipped to that region* onto the QPrinter; issue a QPrinter.newPage(); move the region around; loop until you've covered the whole content area. ... Also, might be a stupid question, but what happens if you use QWebFrame.print() instead of .render()? HTH, -- S. import sys from PyQt4 import QtCore from PyQt4 import QtGui from PyQt4.QtCore import QObject from PyQt4.QtCore import QUrl from PyQt4.QtCore import QSizeF from PyQt4.QtCore import SIGNAL from PyQt4.QtGui import QPainter from PyQt4.QtGui import QPrinter from PyQt4.QtGui import QImage from PyQt4 import QtWebKit class WebKitPDF ( QObject ): def __init__ ( self, url, dest ): QObject.__init__ ( self ) self.dest = dest self.page = QtWebKit.QWebPage ( self ) self.mainFrame = self.page.mainFrame() self.mainFrame.load ( QUrl ( url ) ) self.connect ( self.page, SIGNAL ( "loadProgress(int)" ), self.loadProgress ) self.connect ( self.page, SIGNAL ( "loadFinished(bool)" ), self.renderPDF ) def loadProgress ( self, progress ): print "Progress: ", progress def renderPDF ( self, status ): print "Load finished with status: ", status print "Rendering PDF ..." contentsSize = self.mainFrame.contentsSize() self.page.setViewportSize ( contentsSize ) self.printer = QPrinter ( QPrinter.PrinterResolution ) #self.printer = QPrinter ( QPrinter.ScreenResolution ) self.printer.setOutputFormat ( QPrinter.PdfFormat ) #self.printer.setPaperSize ( QPrinter.A4 ) self.printer.setFullPage( True ) self.printer.setPaperSize ( QSizeF( contentsSize ), QPrinter.DevicePixel ) self.printer.setOrientation ( QPrinter.Portrait ) self.printer.setOutputFileName ( self.dest ) self.painter = QPainter ( self.printer ) self.painter.setRenderHint ( QPainter.Antialiasing ) self.mainFrame.render ( self.painter ) self.painter.end() app = QtGui.QApplication.instance() app.exit ( 0 ) def main( url, dest ): app = QtGui.QApplication ( sys.argv ) wk = WebKitPDF ( url, dest ) sys.exit ( app.exec_() ) if __name__ == "__main__": import sys try: url = sys.argv[1] dest = sys.argv[2] except IndexError: sys.exit() main( url, dest ) ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
[PyQt] Missing scrollbar signal in QPlainTextEdit?
Hi peeps, I'm playing around with QPlainTextEdit and having the weirdest bug. In my application, I've got keyboard shortcuts to scroll the TextEdit up and down by way of the QScrollBar.triggerAction() method, with arguments of SliderPageStepSub and SliderPageStepAdd respectively. I also need to do some stuff when the scrollbar moves, so I bind the scrollbar's valueChanged() signal to the appropriate method. It works all fine when the TextEdit is a QTextEdit. It no longer works when the TextEdit is a QPlainTextEdit. This is really bizarre, because the signal is emitted just fine when: - I move the slider around with the mouse; - I scroll with the mouse wheel; - I trigger the SliderSingleStepAdd/Sub actions instead (with Single instead of Page). And before you bring up QScrollBar.setTracking, I used it and it doesn't change anything. You will find a test case attached herein. Click the buttons to scroll up and down. Then do the same with the mouse. Compare. This is with Qt 4.5.2 and SIP 4.9.1-snapshot-20091015 (the default Ubuntu version). Anybody has any idea what's going on there? A Qt bug maybe? Thanks. -- S. #!/usr/bin/python ## -*- coding: utf-8 -*- import sys import sip from PyQt4 import QtCore, QtGui class ExampleWidget( QtGui.QWidget ): def __init__( s ): QtGui.QWidget.__init__( s ) layout = QtGui.QHBoxLayout( s ) ## Create widgets for left column: l1 = QtGui.QVBoxLayout() layout.addLayout( l1 ) s.text1 = QtGui.QTextEdit( s ) s.text1.setPlainText( u"Some text here.\n" * 100 ) b1up = QtGui.QPushButton( "Scroll up!", s ) b1down = QtGui.QPushButton( "Scroll down!", s ) l1.addWidget( s.text1 ) l1.addWidget( b1up ) l1.addWidget( b1down ) s.connect( b1up, QtCore.SIGNAL( "clicked()" ), s.text1Up ) s.connect( b1down, QtCore.SIGNAL( "clicked()" ), s.text1Down ) ## Create widgets for right column: l2 = QtGui.QVBoxLayout() layout.addLayout( l2 ) s.text2 = QtGui.QPlainTextEdit( s ) s.text2.setPlainText( u"Some other text here.\n" * 100 ) b2up = QtGui.QPushButton( "Scroll up!", s ) b2down = QtGui.QPushButton( "Scroll down!", s ) l2.addWidget( s.text2 ) l2.addWidget( b2up ) l2.addWidget( b2down ) s.connect( b2up, QtCore.SIGNAL( "clicked()" ), s.text2Up ) s.connect( b2down, QtCore.SIGNAL( "clicked()" ), s.text2Down ) ## And set up the connections that demonstrate the bug: s.connect( s.text1.verticalScrollBar(), \ QtCore.SIGNAL( "valueChanged( int )" ), s.hasValueChanged1 ) s.connect( s.text2.verticalScrollBar(), \ QtCore.SIGNAL( "valueChanged( int )" ), s.hasValueChanged2 ) def hasValueChanged1( s, val ): print "QTextEdit has scrolled to position %d." % val def hasValueChanged2( s, val ): print "QPlainTextEdit has scrolled to position %d." % val def text1Up( s ): sb = s.text1.verticalScrollBar() sb.triggerAction( QtGui.QAbstractSlider.SliderPageStepSub ) def text1Down( s ): sb = s.text1.verticalScrollBar() sb.triggerAction( QtGui.QAbstractSlider.SliderPageStepAdd ) def text2Up( s ): sb = s.text2.verticalScrollBar() sb.triggerAction( QtGui.QAbstractSlider.SliderPageStepSub ) def text2Down( s ): sb = s.text2.verticalScrollBar() sb.triggerAction( QtGui.QAbstractSlider.SliderPageStepAdd ) app = QtGui.QApplication( sys.argv ) widget = ExampleWidget() widget.show() app.exec_() ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
[PyQt] More QPlainTextEdit weirdness! (was: Missing scrollbar signal...)
On Friday 11 December 2009 07:28:27 Henning Schröder wrote: > I have looked at the source of QPlainTextEdit and QTextEdit. Actually the > implementations are not consistent. > QPlainTextEdit calls verticalBar.blockSignals(True) before it call setValue > which would otherwise emit valueChanged. Hi guys, hi Henning, This is what's awesome about this mailing-list: you bring up the most obscure issue, and there's someone with a helpful and interesting answer for you. Brilliant! In my case I worked around the problem by sending the signal manually after calling triggerAction(). Not very clean, but that's workarounds for you. But in the meanwhile more QPlainTextEdit weirdness crept up. As part of a helpful little feature that shows you the bottom of your text in a split screen while you scroll back, I use the awesome QTextDocument.drawContents() method. In short, you feed it a QPainter and a QRectF and it does what it says on the label: a slice of your document as delineated by the QRectF is rendered onto the QPainter. There is, as far as I can tell, no difference between the QTextDocument returned by QTextEdit.document() and QPlainTextEdit.document(). Same class in both cases. And yet in the latter case, drawContents() renders nothing at all. Cursory investigation points to a different QAbstractTextDocumentLayout implementation under the hood depending on the TextEdit flavor in use. So I think I'm going to drop QPlainTextEdit entirely, even though in theory it's better suited to my problem domain. After a few tests, the benefits in speed and memory usage are not obvious anyway. (Which is possibly a testament to QTextEdit's efficiency, when you think of it.) But alternative viewpoints would be welcome! Bye, -- S. ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
Re: [PyQt] More QPlainTextEdit weirdness! (was: Missing scrollbar signal...)
On Friday 11 December 2009 14:04:41 Henning Schröder wrote: > Have you tried plaintext_edit.document().documentLayout().draw(paint, > context) ? Thanks! Actually, I have since switched to the use of QAbstractTextDocumentLayout.draw(), because unlike QTextDocument.drawContents() it can paint the current selection as well, but my code has since come to depend more on the specifics of QTextEdit anyway, so replacing it with QPlainTextEdit is no longer very interesting. But thanks for the pointer! Had I not come across that method on my own in the meanwhile, it would have been invaluable to me. Bye, -- S. ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
[PyQt] Asynchronous QSound.isAvailable()?
Greetings all, I'm having a problem I don't know how to address. Just plain completely at a loss. The issue: on Linux, when the NAS sound server isn't installed (which is the case on most distros nowadays), QSound.isAvailable() blocks for several seconds before returning. Since it runs in the main thread, it blocks the UI as well. I've tried to poll for sound availability in a different thread, and then another problem occurs: QObject: Cannot create children for a parent that is in a different thread. (Parent is Application(0x26ba030), parent's thread is QThread(0x279d510), current thread is EnginePollerThread(0x2b22040) EnginePollerThread is the QThread subclass where I call QSound.isAvailable() Apparently, whatever object the static method isAvailable() uses is parented to the main thread, and I'm at a loss as to how to reparent it, or otherwise make the warning go away. I'm thus looking for a mean, any mean, to run QSound.isAvailable() asynchronously. Any pointer, anyone? Thanks. -- S. ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
Re: [PyKDE] Sugestions for PyQt4
I heard Giovanni Bajo said: > As I said elsewhere, I believe this kind of improvements belongs to a > separate wrapper, such as PyPyQt built on top of PyQt. Others would > prefer a PyQt compilation switch or something like that. Hello Giovanni, I'd cast my vote in favor of a wrapper. I think we already brought up the idea when discussing the Qt namespace issue. Essentially, it does make a lot of sense to provide the C++ Qt API 'as is' to people migrating from C++ to Python, but the majority of the PyQt developper community, as far as I can tell, is made of experienced Python programmers, and a more Pythonic interface would make a lot of sense as well. Now, though, do we make that a separate project, or something that would ship with PyQt as it currently exists? (And by this I mean, really, Phil, do you want to have your hands in that wrapper, or would you rather it be a community project?) -- S. ___ PyKDE mailing listPyKDE@mats.imk.fraunhofer.de http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] PyQt4 compilation failure: location of specs?
I heard Phil Thompson said: > Tonight's PyQt4 snapshot gets the various Qt directories from > QLibraryInfo rather than assuming a standard layout. Phil, Everything is configured and compiles fine except pylupdate, which fails to include the correct mkspecs directory. The INCPATH is set correctly in qtdirs.mk; the Makefile in pylupdate/ fails to include it, though. What information would you need to look into that issue? The mkspecs dir here is /usr/doc/qt-4.1.2/mkspecs/linux-g++ but the Makefile in pylupdate/ includes /usr/mkspecs/linux-g++ instead... With kind regards, -- S. ___ PyKDE mailing listPyKDE@mats.imk.fraunhofer.de http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] PyQt4 compilation failure: location of specs?
I heard Phil Thompson said: > Should be fixed in tonight's SIP and PyQt4 snapshots. Unfortunately > this means that there will be a SIP 4.4.2 when PyQt4 is released. Hi Phil, I am sorry to report that I tried SIP and PyQt4 snapshots of 2006/04/08, and there seemed to be the same problem. Should I try more recent snapshots still? Thank you, -- S. ___ PyKDE mailing listPyKDE@mats.imk.fraunhofer.de http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] Eric 3.9 reopen last project
I heard Andreas Pakulat said: > > The last project should be the topmost entry. > > Seems I should've added: automatically upon startup :-) Please don't! :) Some can have several ongoing projects at once and don't necessarily want to work on the last one opened when they fire up Eric3. However, making it a command line option would probably be a good idea. What do you think, Detlev? -- S. ___ PyKDE mailing listPyKDE@mats.imk.fraunhofer.de http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
[PyKDE] Deleting a layout in PyQt as opposed to Qt...
Hi peeps, The Qt documentation informs us that the proper way to replace the layout on a widget is to first delete the current layout and then install a new one. Setting a new layout before the previous one is deleted won't work. All fine and dandy. The C++ syntax for removing a widget's layout is: delete widget.layout(); However, the Python equivalent does not work: del widget.layout() In Python, del only unlinks the named reference from its current namespace, triggering the actual deletion if the object's refcount falls to 0. Meaning that 1) you can't call del on the method call itself, and 2) if you assign the method call's return value to a local variable to be deleted, then del only unlinks that variable but the layout itself still has a reference from the widget, and is thus not deleted. Am I missing something? Is this an oversight in PyQt, or is there a nice, clean Python equivalent that I've overlooked? Thanks! -- S. ___ PyKDE mailing listPyKDE@mats.imk.fraunhofer.de http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
[PyQt] Exception handling hook
Arve Knudsen wrote: > Is it possible to register a hook with QApplication in order to be > notified of an unhandled exception? Hi Arve, Exceptions live in the Python realm, so they have nothing to do with QApplication as far as I know. You can install an exception handler with sys.excepthook. Here's a PyQt3 example (which might also work with PyQt4, I haven't tested): def handle_exception(exc_type, exc_value, exc_traceback): filename, line, dummy, dummy = \ traceback.extract_tb(exc_traceback).pop() filename = os.path.basename(filename) error = "%s: %s" % (str(exc_type).split(".")[-1], exc_value) QMessageBox.critical(None, "ERROR", "There has been an error: " + "%s " % error + "on line %d, file %s" % (line, filename)) You can (and probably should) close your application then. You can install this handler with: sys.excepthook=handle_exception (Since the handler uses QMessageBox, install it AFTER instanciating your QApplication.) Bye, -- S. ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
[PyQt] Exception handling hook
Arve Knudsen wrote: > If an exception is raised in the last Python > layer, it is swallowed by the excepthook and a nice message box pops > up, BUT once control returns to the first Python layer Hi again, In my opinion, the exception hook should never even return. That's what I meant when I said your application should then close. When you're dealing with an uncaught exception anyway, something has gone wrong and it is generally wise not to attempt to keep running, lest data corruption and bad karma occur, in that approximate order. I am not sure that what you seem to be asking for is at all possible -- it would involve making the Qt event loop aware of Python exceptions, I think, which doesn't at all sound like good Feng Shui to me. If you really, really want to deal with Python exceptions at the outermost possible level (which will still be inside the Qt event loop level, mind), then I guess you should make an exception hook that will store the exception stack in some global variable, push some manner of custom event to the application's main event queue (or put the exception stack /in/ the custom event), then return, and have a custom event handler pull the exception stack off that custom event and only THEN process it. And quit. Theorically feasible, I would imagine. But I still think that quitting the application right away would make less baby angels cry, mind. Hope this helps nonetheless! -- S. ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
Re: [PyQt] PyQt v4.3a1 Binary Installer for Windows
Phil wrote: > I've created a binary Windows installer for what will be PyQt v4.3 at > http://www.riverbankcomputing.com/Downloads/PyQt4/GPL/PyQt-gpl-4.3a1-Py2.5.exe Oh, wonderful! Thank you Phil, this will make deploying stuff on Windows that much easier. :) Speaking of which, Giovanni -- if I remember correctly (which I may not, on account of silly brain), you mentioned to me having worked on a PyQt installer mode where everything is compiled statically inside a single .pyd, leading to drastic space reduction. Did you get it into any sufficiently good shape that the rest of us could use it to ship PyInstaller-made packages for PyQt software that actually don't weigh in the tens of MBs? That'd be awesome. :) Thanks, -- S. ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
Re: [PyQt] PyQt v4.3a1 Binary Installer for Windows
Giovanni wrote: > It wasn't a PyInstaller mode, it was just a way of compiling PyQt. I > spoke of this to Phil and he agreed to implement it directly within > SIP/PyQt. The above installer is the result of his work. Oh, THANK YOU for this, Giovanni, Phil. I've long wished for a way to package PyQt applications on Windows without too much overhead, and this looks like the definitive answer. Kudos to you guys! :) -- S. ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
Re: [PyQt] About keyPressEvent
Gustavo A. Díaz wrote: > As i said, only Escape key. > > I want to know to do the same but with alt + Escape... or which > is the way to do it... Hi Gustavo, I am not sure I understand what it is that gives you trouble here. Is it that you don't know how to go about it, or is it that it doesn't work properly for you? In case it's the former, you will probably want to wrap the window hiding code under a QAction, and give that QAction the shortcut 'Alt+Esc' with QAction.setShortcut(). Remember that a QAction must be added to a widget (with QWidget.addAction()) before its shortcut will work. With kind regards, -- S. ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
Re: [PyQt] About keyPressEvent
Gustavo A. Díaz wrote: > But this method is applied when you have a Menu bar right? No. This method is applied when you add an action to a QWidget, as I said in my previous email. It just so happens that if the QWidget is a menu or a toolbar, Qt creates a menu entry or a toolbutton, respectively, but you can also add a QAction to any other widget. Okay, so. Before anything else -- sorry for asking, but you never know -- did you make sure that the Alt+Esc shortcut is not being preempted by something else, like your window manager for instance? -- S. ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
Re: [PyQt] Re: Note about setting setting painters with gradients instead of brushes
Phil Thompson wrote: > Works fine for me. Doesn't work for me though: [EMAIL PROTECTED]:~$ python test.py no workaround Traceback (most recent call last): File "test.py", line 49, in paintEvent painter.setBrush(g) TypeError: argument 1 of QPainter.setBrush() has an invalid type QPaintEngine::setSystemRect: Should not be changed while engine is active QPaintEngine::setSystemClip: Should not be changed while engine is active QPaintEngine::setSystemClip: Should not be changed while engine is active QPaintEngine::setSystemClip: Should not be changed while engine is active That's on Kubuntu with PyQt 4.1 and SIP 4.5. -- S. ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
Re: [PyQt] Re: Note about setting setting painters with gradients instead of brushes
Phil Thompson wrote: > I've already said that you need PyQt 4.2 or later. Blargh, you're right -- sorry! -- S. ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
[PyQt] Eric3 issue: importing modules with the same name as an Eric module
Hi peeps, I am trying to run a Python/Qt4 project in Eric3. The project has a file called Config.py. When I try to run the project from the Eric3 interface, it fails, because the line 'import Config' in my code imports the Config module from Eric3 instead, even though my project directory comes first in sys.path. Is there anything I can do to keep Eric3's own modules out of the way of my imports? Thanks, -- S. ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
Re: [PyQt] Eric3 issue: importing modules with the same name as an Eric module
Detlev Offenbach wrote: > That is strange. eric puts the path of the executable at sys.path[0] > just before it's own path. Can you check sys.path in your main > routine or just before the failing import? Hi Detlev, Thank you for your reply! I did check sys.path just before the failing import. This being said, I don't think sys.path is used at all here, as you will see below. Anyway, here's how to reproduce the bug: create these two files: ---[ test.py ]- import sys print "Path:" print sys.path import Config print "Config file:" print Config.__file__ --- ---[ Config.py ]--- print "I am the Config.py file!" --- ... and run test.py from Eric. The output will be something like this: ---[ (output) ] Path: ['/home/me', '/usr/share/eric/modules/DebugClients/Python', '/usr/share/eric/modules', ...] Config file: /usr/share/eric/modules/DebugClients/Python/Config.pyc --- As you can see, the sys.path is correct, but the wrong Config module is imported. What is happening here is, I think, that the Python interpreter instance which Eric starts in order to run my program, isn't 'clean': it imports its own Config module BEFORE even running my code, and thus, when my code tries to 'import Config', that Python interpreter goes, "Oh, but I already have a Config module loaded, so I'll just return a reference to that one". Am I correct in my assumption that the Python interpreter instance loads its own Config module before running my code? Or is it a bug? Thanks, -- S. ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
Re: [PyQt] Eric3 issue: importing modules with the same name as an Eric module
Detlev wrote: > You are right! And here are instructions for fixing it. Hi Detlev, Awesome! Thank you for this! Don't we risk bumping into the very same problem if somebody ever tries to run something with a DebugConfig module in Eric though? In that spirit, I think I've found a more robust fix for the issue: In file 'DebugClients/Python/DebugClientBase.py', replace the line: from Config import ConfigVarTypeStrings ... with: from DebugClients.Python.Config import ConfigVarTypeStrings I've tested that it fixes my issue: with this modification, my own Config module imports correctly and my project runs fine within Eric. However, I cannot say if there are other module names that could conflict with the Eric debugger. Presumably, applying the same fix would work fine too, though. With kind regards, -- S. ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
Re: [PyQt] Eric3 issue: importing modules with the same name as an Eric module
Detlev wrote: > Your fix doesn't work over here. It seems, that there is more about > it. Aw crap. :) What version of Eric is it, running on what version of Python, and what's the problem: does the fix cause it to not work in a different way, or does it just fail to fix the problem I reported? Mind you, I am not all that familiar with the nitty-gritty details of how the module cache works, but I was under the impression that the name of the keys of the sys.modules dictionary was what was used to determine whether an import statement should try looking up the module, or just return a reference to the already loaded module. What my fix was supposed to do, was thus put 'DebugClients.Python.Config' in sys.modules instead of 'Config'. What output do you get for this script: ---[ test.py ]- import sys print [ m for m in sys.modules if "Config" in m ] --- ... when you run it, respectively with a patched DebugClientBase.py and with an unpatched one? Myself, I get ["DebugClients.Python.Config"] and ["Config"], respectively, which is the behavior I expected. Thanks, -- S. ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
Re: [PyQt] Eric3 issue: importing modules with the same name as an Eric module
Detlev wrote: > Over here it failed to start the debug client because of an > ImportError. It cannot find the file, if the long import is given. Hi Detlev, I worked on it over the weekend on a different flavour of Linux, and I noticed the same issue you do. Apparently different distros package Eric in different ways. On Ubuntu (and presumably Debian) the fix works with "from DebugClients.Python.Config import ...", while on Gentoo it requires "from eric3.DebugClients.Python.Config import ...". Since the Eric documentation DOES refer to the DebugClients package as 'eric3.DebugClients' (see documentation file index-eric3.DebugClients.html), I'll go and assert that it's probably Ubuntu/Debian being silly and packaging stuff their own way here. Meaning that the fix should go: -from Config import ConfigVarTypeStrings +from eric3.DebugClients.Python.Config import ConfigVarTypeStrings ... And let Debian and friends fix their packaging. Once more, however, the same treatment should probably be applied to the other packages that the debug client imports locally. Or if you'd rather, I can try to look into how feasible it'd be to create a custom import hook that would isolate the debugger's imports from that of the user code. I, uh, I hope I'm not bothering you with my repeated attention to this admittedly minor issue? Thanks, -- S. ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
Re: [PyQt] Eric3 issue: importing modules with the same name as an Eric module
Detlev wrote: > Actually it is not a minor issue. If possible I would try the import > hook approach. Would you take this task? Hi Detlev, As time allows, yes, with pleasure. No promise about how successful it's gonna be, though, seeing as we're talking badass advanced snake charming here; we'll see how that goes. > Btw, your email address gives errors (not deliverable). I know -- I understand the primary DNS for that domain is kaput. And since neither the domain host or the DNS server host respond to my queries, I'm essentially screwed for the time being. That's why I read this mailing-list through an RSS feed, and why my replies break threads, incidentally. -- S. ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
Re: [PyQt] Eric3 issue: importing modules with the same name as an Eric module
Sundance wrote: > As time allows, yes, with pleasure. No promise about how successful > it's gonna be, though, seeing as we're talking badass advanced snake > charming here; we'll see how that goes. ... Ookay. This was even worse than I imagined, but I'm done and, crazily enough, it seems to work. Here's how it works. 1) Drop the attached source file in the debugger's directory; 2) Surround the imports to be quarantined with the code that loads and turns the quarantined import on, then off. For instance: ---[ Unquarantined imports ]--- import A import B from C import D --- ... becomes... ---[ Quarantined imports ]- from QuarantinedImport import quarantined_import quarantined_import.on() import A import B from C import D quarantined_import.off() --- In Eric's case, that would make it: ---[ DebugClientBase.py excerpt ]-- [...] from QuarantinedImport import quarantined_import quarantined_import.on() from DebugProtocol import * import DebugClientCapabilities from DebugBase import printerr from AsyncFile import * from Config import ConfigVarTypeStrings from FlexCompleter import Completer quarantined_import.off() [...] --- And yeah, that's it. Warning: this tool is pure evil, it comes with no warranty whatsoever and may eat kittens and/or puppies. Also, if there's a module that does some very important things at load time that must only happen once, all hell will likely break loose if you import that module both inside and outside the quarantined zone. Consider yourself warned. Feedback very welcome! -- S. QuarantinedImport.py Description: application/python ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
Re: [PyQt] Eric3 issue: importing modules with the same name as an Eric module
Hi Detlev, Okay, I can't reproduce the issue you're describing (although I have an idea what causes it). May I ask you to give me a simple test case and, if at all possible, a traceback? Thanks! As for my email, things have been progressing at last, only to see new hurdles surface, joy. I'll send you a private email from a working address. With kind regards, -- S. ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
[PyQt] Message boxes or OSD
Nahuel wrote: > I wonder if I could make nice notifications similar to kdialog's or > maybe something like amarok osd. Hi Nahuel, I'd make it a custom QWidget with the FramelessWindowHint flag. I refer you to the 'Shaped Clock' example of the Qt documentation: http://doc.trolltech.com/4.3/widgets-shapedclock.html The Python equivalent, 'shapedclock.py', ships with the documentation and examples of recent releases of PyQt 4. Just have the widget paint your OSD instead of a clock and I'd say you have a good basis to work from. :) HTH, -- S. ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
[PyQt] Handling the uncaught exceptions
Hi Peter, > Is there a way to handle the uncaught exceptions that happen in PyQt? Yup: install your own exception handler in sys.excepthook. You'll find a somewhat fancy exception handler I wrote a while back as the handle_exception() function (starting line 146) in this file: http://spyrit.svn.sourceforge.net/viewvc/spyrit/trunk/Utilities.py?revision=99&view=markup The gist of it is, any function that takes the parameters exc_type, exc_value and exc_traceback, and DOESN'T use exceptions internally, will serve. Do note that your PyQt application will /not/ exit after calling the exception handler, so if you want that, call sys.exit() right in your exception handler. HTH, -- S. ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
[PyQt] KDE Plasmoids in Python
Greetings, good folks of various sizes and shapes, Has anyone, and I'm especially turning to our fine PyKDE people here, successfully gotten a Python Plasmoid (applet, data engine, runner, whichever) to work in KDE 4, either 4.0 or in trunk? I have been looking into it and generally remained baffled about how to go about it -- Aaron 'Awesome' Seigo pointed me to ScriptEngine in playground, but that's about where I'm stuck at this point: Plasma doesn't seem to register the example Python Plasmoids that ship in playground/base/plasma/scriptengines/kross/, and I don't really know where to begin looking. Thanks, -- S. ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
[PyQt] Can I create more than one instance of a class?
Hi Adonay, > Hi, I'm programing a little app which needs to open more than one > time, the same window. > Now I make an import and instance the window like this. > > from new_window import * Bad idea. As a rule of thumb, you don't want to use 'import *' when you can avoid it. It's okay while your app is small; but once it grows, trust me, you'll be glad you can tell at a glance what comes from what module. So you may want to learn the best practice right away and avoid 'import *'. :) > a = new_window > a.show() > b = new_window > b.show() > c = new_window > c.show() You are referencing the SAME instance, 'new_window', in all cases! If you want different instances, you need to instantiate your class each time. So, assuming your class is called MyWindow, your code should look like: from MyWindow import MyWindow ## Give the module a descriptive name too! a = MyWindow() a.show() b = MyWindow() b.show() c = MyWindow() c.show() print a, b, c Perhaps your are not very well at ease with how Python works yet? If so, there are excellent tutorials out there: - http://docs.python.org/tut/ - http://www.diveintopython.org/toc/ HTH, -- S. ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
Re: [PyQt] Virtual methods and an extra reference
Kevin Watters wrote: > I'm tracking down a memory leak in my app--and I think it's boiling > down to a virtual method on one of my classes that has an extra > reference, one not coming from any Python object. Hi Kevin, hi Phil, hi all, Okay, Kevin, you MUST be reading my mind because, first thing I did this morning after yesterday evening's work was fire up my email client and start a message entitled "Serious memory leak in PyQt?". I can confirm the issue and, perhaps, provide a little more data. The core issue is the way Python handles references around bound methods. Let obj.meth() be a method on an object. By default, the reference count to the bound method is zero, and the reference count to the object is, exactly, the number of external references you have to that object. I am not sure how it is that the refcount to the bound method is zero by default. I suspect it may have to do with the way methods are implemented in Python; i.e. the method is not on the object but on the /class/, and the method is only bound to the /object/ at call time. Let us now extract the bound method under an external label: m = obj.meth The method object returned by the implicit getattr is /bound/: it comes with a closure that contains the object the method is bound to, and that object's refcount thus increases by one. And here's the issue: what PyQt (well, SIP, really) seems to do with virtual methods that are reimplemented in Python, is grab a reference to the bound method, and /never let it go/. Hence, your bound method's refcount never returns to zero. Hence, your /object's/ refcount never returns to zero. And you get a memory leak. This is an issue because all the event management in Qt is done with virtual methods. Example code: ---[ Code ] import sys from PyQt4 import QtGui app = QtGui.QApplication( sys.argv ) class MyWidget( QtGui.QWidget ): def resizeEvent( s, e ): print "In resizeEvent." return QtGui.QWidget.resizeEvent( s, e ) def __del__( s ): print "%s deleted." % s class MyOtherWidget( QtGui.QWidget ): def nonVirtualMethod( s ): print "All's good." def __del__( s ): print "%s deleted." % s ## Let us now test all the possible cases. obj1 = MyOtherWidget() obj1.nonVirtualMethod() del obj1 ## No virtual method, no problem. obj2 = MyWidget() del obj2 ## Virtual method never used, no problem. obj3 = MyWidget() obj3.show() ## resizeEvent is bound by SIP. app.processEvents() obj3.close() del obj3 ## ... But never released. Memory leak. --- Usually this wouldn't be a huge issue, but when you are creating and destroying lots of widgets, suddenly it's a thorny problem. Phil, may we please discuss possible ways to fix this? It might be as simple as using weak references to the bound methods instead of direct references. Arguably, 'simple' is perhaps something of a misnommer, because Python's weakrefs don't handle bound methods well at all (the weak reference dies the moment the bound method goes out of scope). Fortunately, that can be worked around reasonably simply: ---[ Code ] import weakref class WeakCallableRef: def __init__( s, fn, callback=None ): assert callable( fn ) s._methname = None s._objref = None s._fnref= None s._dead = False s._callback = callback obj = getattr( fn, "im_self", None ) if obj: ## fn is a bound method s._objref = weakref.ref( obj, s.markDead ) s._methname = fn.im_func.func_name else: ## fn is a static method or a plain function s._fnref = weakref.ref( fn, s.markDead ) def markDead( s, ref ): s._dead = True if s._callback: s._callback( s ) def __call__( s ): if s._dead: return None if s._objref: ## bound method return getattr( s._objref(), s._methname, None ) else: return s._fnref() --- This class behaves like weakref.ref, only for callables. Might it be possible to have it used by PyQt for virtual methods? Thanks, -- S. ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
[PyQt] Re: Virtual methods and an extra reference
Kevin wrote: > Obviously the usage of the above bound_ref is just for bound > methods--but I think using new.instancemethod is more correct than > lazily grabbing the bound method with getattr. Hi Kevin, I like the use of new.instancemethod. I like it a /lot/. However: I notice that your code increases the refcount to both the class and function object as a side effect of creating the weak reference, which gives me pause. Has this been a problem for you? > The only issue > remaining is to whip up a C implementation :-) This is important > enough that I'll try to look into it today, Have you made progress on this? In the meanwhile, I've been able to work around the memory leak by: 1) Renaming all my whateverEvent() methods to _whateverEvent(), and 2) Implementing a __getattr__() that returns WeakCallableRef(self._whateverEvent) when whateverEvent is requested. At first I tried to make it work with a decorator, which would arguably have been remotely cleaner, but it works not, because the decorator acts on the unbound function object, not on the bound method. The workaround makes my skin crawl. :| I hope you'll be able to whip up a fix, Kevin. -- S. ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
Re: [PyQt] Re: Virtual methods and an extra reference
Phil wrote: > I will look at this properly when I have the time. Thank you, Phil -- it's appreciated. In the meanwhile, for those who may come across this thread in the future, here's a working workaround (as opposed to the almost-working- but-not-quite one from earlier *g*): 1) Rename the problematic methods, for instance by putting an underscore in front: paintEvent() becomes _paintEvent(). 2) In your object's constructor, add such a line as: s.paintEvent = WeakCallable( s._paintEvent ) 3) Add somewhere the following code: ---[ Code ] import new from weakref import ref, ReferenceError class WeakCallableRef: def __init__( s, fn, callback=None ): assert callable( fn ) s._methname = None s._objref = None s._fnref= None s._dead = False s._callback = callback obj = getattr( fn, "im_self", None ) if obj: ## fn is a bound method s._objref = ref( obj,s.markDead ) s._fnref = ref( fn.im_func, s.markDead ) s._class = fn.im_class else: ## fn is a static method or a plain function s._fnref = ref( fn, s.markDead ) def markDead( s, ref ): if not s._dead: s._dead = True if s._callback: s._callback( s ) def __call__( s ): if s._dead: return None if s._objref: ## bound method fn = s._fnref() obj = s._objref() if None not in ( fn, obj ): return new.instancemethod( fn, obj, s._class ) else: return s._fnref() class WeakCallable: def __init__( s, fn ): s._ref = WeakCallableRef( fn ) def __call__( s, *args, **kwargs ): fn = s._ref() if fn: return fn( *args, **kwargs ) raise ReferenceError( "Attempted to call dead WeakCallable %s!" \ % s ) --- ... And you should be good. The above aggregates the feedback from this thread -- thank you, Kevin! -- into one neat, reasonably simple if generally loathesome workaround. Goodness, how I hate workarounds. -- S. ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt