I'm developing a python plugin for Rhythmbox - this contains a GtkScrolledWindow with a child which is a GtkIconView. The IconView is fed from a Gtk.TreeModel.
It looks like this:
Currently - and somewhat inefficient, every icon is drawn for every row in the tree-model - each icon is a GdkPixbuf from a file. If you have thousands of rows, it can take quite a while for the whole iconview to be fully updated with every picture icon.
What I am trying to achieve is to only update the icons that are in the current drawing area - when the user scrolls and releases the scrollbar (or navigates via the keyboard), the icons in the new drawing area should be updated with relevant pictures.
N.B. - the tree-model would be fully populated at this point - only the icons would not have been loaded.
This is not really my area of expertise - I'm looking for pointers for the best approach I should use to achieve the above.
Specifically - which Gtk+3 drawing-area signal (or signals) can be exposed (Gtk.ScrolledWindow / Gtk.IconView ?) to write python code to calculate what icons should be updated?
You should profile you application to see what takes time.
Is that loading the images ? If it is, then loading a default image and adding it everywhere in your view would be quick enough, as you'd load only one image. You'd then load and update the images on-demand using idle_add, based on the images that should appear in the viewport.
If what takes times is adding the images to the model, then you'd need to do the adding on-demand, by checking what is visible on the viewport in your idle_add callback.
If both are slow, you'd need a mix of both solutions: loading and adding on-demand.
Think also about the proxy design pattern that can be useful to create a fake cover object that will load in the background, and contain the loading policy.
For the signals, your GtkIconView widget implements GtkScrollable, which explains how to implement scrolling. You'd set your vertical adjustment and check when it has changed by connecting to its value-changed signal. This would mean the user scrolled up or down, and you'd need to fire up a timer with timeout_add. If after a short timeout (between 0.5 and 1s I think, but needs testing), the adjustment hasn't changed, this means the user stopped scrolling, and you can update what is displayed. Otherwise, it would be updated during the scrolling, slowing everything down. You then just need to figure out how to find which items appear in the viewport, to update their cover.
I've never done this before though, but I know GTK a bit and just tried to figure out how it would be done, so read that with a bit of caution. Anyway, the answer to reactivity is "on-demand".
But on the other hand if you have to scroll completely down, you would have to wait for every page to be build. So i guess you should better consider the idle_add function of the event loop.
This way your screen doesn't lock up and your pc doesn't have to wait for the user to load the view page for page. Win-Win for you and your application. ;-)
Related
This question is about Veusz, a python-based plotting program. Not about usage, but about where to start hacking to fix a particular problem... This is on Windows.
Currently, when the program is launched it starts non-maximized, even if it was maximized last time it was closed. I can modify the shortcut to always start maximized but new windows opened within the app are always non-maximized.
Although it doesn't remember its maximized state, it does remember the size of last non-maximized window. As a workaround, I tried positioning the program top-left and resizing it as if it were maximized. However, when I open new windows from this one, they are offset from the top-left corner by the height of the "window bar". The offset does not cascade though; that is, opening a new window from an offset one results in a window in the same position.
I've been pawing through the program's files looking for somewhere window position might be saved or a default might be set. Not seeing anything, though. This is a Qt app so perhaps it's not Veusz-specific but I'm inclined to think it is. Spyder, for instance is Qt-based but I don't see this problem with it.
Does the community have any suggestions regarding changing this behavior? I don't understand the setup routine well enough yet. The source is on Github if you're feeling that helpful.
The relevant code is here in functions closeEvent (for saving state) and setupWindowGeometry (for loading state).
https://github.com/jeremysanders/veusz/blob/master/veusz/windows/mainwindow.py
Veusz needs to save the state of the window, as well as the geometry. Maybe doing something like this http://doc.qt.io/qt-4.8/restoring-geometry.html
I've got a program which is using multiple monitors. The program is showing special visualizations on the second monitor. At one point, the program uses windows shell functions to send files to the recycle bin. However, when it does this, the delete confirmation dialog comes on top of my visualization. This is particularly problematic, as when the mouse is on the second monitor, my program uses mouse hooks to capture all mouse input, so the user cannot even click the confirmation dialog.
Is it possible to somehow tell Windows to only place dialog boxes on a particular display?
I'm using python, though if I have to call C WinAPI functions that shouldn't be a problem
which function are you using to send the files to the recycle bin? if you use SHFileOperation you can pass a parent HWND. perhaps make that an invisible WS_EX_TOOLWINDOW window on the other monitor.
i would expect the API, treating that window as a parent, would center relative to that window, but i haven't tried it.
depending on which version of Windows you are targeting, there used to be a capability to create desk bands that 'dock' to the sides of the screen. this automatically gets factored into the area returned as rcWork by GetMonitorInfo and should prevent dialogs from overlapping this space. There might be another way to declare that a region is "in use" in a way that declares space off-limits, but I don't know of it so it probably doesn't exist...
the ugly and crude thing you could do is poll and move the dialog yourself, but if this is any kind of widely deployed or commercial app that would likely cause more harm than good.
I'm new to QT. I'm using PyQT for GUI development in my project. I want to achieve this layout in my application. This application searches images from an image database. Google image search layout is ideal for my purpose.
I'm following the book "Rapid GUI Programming with Python and Qt" and I'm familiar with layouts. I guess I need to use a grid layout with each result image in each box of grid. & use vertical layout for (image,Qlabel,Qlabel) inside each grid box.
These are some problems I'm facing.
Importantly, I'm unable to display image. What control/widget do I need? I cannot find anything similar to PictureBox of .NET
How do I seperate these image result by fixed gap like in the image? I'm using Horizontal & vertical spacers but that isn't working?
How to set QLabel a clickable (like hyperlink). I don't want to a open a URL. Just the text should be clickable. So, that when user clicks on the link. I can show more information (like next set of results when he clicks on next page number or a new window with image in fullsize when user clicks on 'view') Do we have some new kind of control for this?
This is another important issue. I'll display the page numbers of results (like shown in figure) & assuming they are clickable. How do I load a new page of results? I mean what is the equivalent of page in QT?
As you can guess. This definitely wont be the first page of GUI. The first page will be exactly like http://google.com (a big logo & text box with button below it). when user clicks the search button. This page will be displayed. Again the same question comes up. How change the pages?
Please give a list of controls I'm going to need for this. Tell me if I'm unaware of something.
1/2.
For displaying the images and labels use a QListWidget with view mode set to QListView::IconMode. However, if you need to customize the display beyond what the QListWidget/QListWidgetItem api can provide you will need to create your own QAbstractListModel and use a standard QListView with it.
Make sure and read Qt's primer on model/view.
As for spacing the images, checkout the spacing property on the list view.
Here is an example from KDE's Dolphin file manager:
3. Use a regular QLabel, but set the contents to be an href.
Example:
edit: Oops I see from your tags you are using PyQt, the following is C++, but should be similar to what you would do in python.
QLabel *linkLabel = new QLabel;
linkLabel->setTextFormat( Qt::RichText )
linkLabel->setText( " Click me! " );
connect( linkLabel, SIGNAL( linkActivated ( const QString & link ) ), .... )
4.
Well, since you are using a Model/View, why bother having page numbers at all? The user will just be able to scroll the view and more pictures will be shown. This is by far the easiest solution as you don't have to do anything once you've got your M/V setup!
However, if you really want to show page numbers it will require more work in your model. For example, have a track the "current page" in the model and only allow access to images on the "current page". Then in your slot connected to the linkActivated() signal tell the model to change pages. I won't go into much more detail as this seriously violates the whole idea behind model/view. The "right way" of doing this would be to subclass QListView and add pagination support, but like I said why not use scroll bars? There isn't any performance hits to doing so.
5. Use a QStackedWidget, addWidget() all your "pages" to it, then call setCurrentIndex/Widget() as needed to switch the pages.
Thoughts:
It seems you are very committed to cloning the look, feel, and behavior of Google Image search, which is fine, but Google Image Search is a web application that uses interaction paradigms that are very different than a normal desktop application (links, pages, etc). You are presumably developing a desktop application, and by trying to emulate the behavior of a web app you will find it difficult as the API just isn't designed to support those sorts of interactions. By all means, it is doable, but you'll have your work cut out for you.
If you are extremely intent on sticking to the web based interaction style, why not code your app in javascript and HTML and toss it in a QWebView?
Try using QListWidget with viewMode set to IconMode. It should do all for you. BUT if you need to customize your data display use QListView with your own/standard model and own delegate for painting
I would like to create an application that has 3-4 frames (or windows) where each frame is attached/positioned to a side of the screen (like a task bar). When a frame is inactive I would like it to auto hide (just like the Windows task bar does; or the dock in OSX). When I move my mouse pointer to the position on the edge of the screen where the frame is hidden, I would like it to come back into focus.
The application is written in Python (using wxPython for the basic GUI aspects). Does anyone know how to do this in Python? I'm guessing it's probably OS dependent? If so, I'd like to focus on Windows first.
I don't do GUI programming very often so my apologies if this makes no sense at all.
As far as I know, there's nothing built in for this.
When the window is hidden, do you want it completely invisible or can a border of a few pixels be showing? That would be an easy way to get a mouse hover event. Otherwise you might have to use something like pyHook to get system-wide mouse events to know when to expand your window.
The events EVT_ENTER_WINDOW and EVT_LEAVE_WINDOW might also be useful here to know when the user has entered/left the window so you can expand/collapse it.
Expanding/collapsing can just be done by showing/hiding windows or resizing them. Standard window functions, nothing fancy.
By the way, you might want to use wx.ClientDisplayRect to figure out where to position your window. That will give you a rectangle of the desktop that does NOT include the task bar or any other toolbars the user has, assuming you want to avoid overlapping with those things.
Personally, I would combine the EVT_ENTER_WINDOW and EVT_LEAVE_WINDOW that FogleBird mentioned with a wx.Timer. Then whenever it the frame or dialog is inactive for x seconds, you would just call its Hide() method.
I think you could easily just make a window that is the same size as the desktop then do some while looping for an inactivity variable based on mouse position, then thread off a timer for loop for the 4 inactivity variables. I'd personally design it so that when they reach 0 from 15, they change size and position to become tabular and create a button on them to reactivate. lots of technical work on this one, but easily done if you figure it out
I'm not familiar with PowerBuilder but I have a task to create Automatic UI Test Application for PB. We've decided to do it in Python with pywinauto and iaccesible libraries. The problem is that some UI elements like newly added lists record can not be accesed from it (even inspect32 can't get it).
Any ideas how to reach this elements and make them testable?
I'm experimenting with code for a tool for automating PowerBuilder-based GUIs as well. From what I can see, your best bet would be to use the PowerBuilder Native Interface (PBNI), and call PowerScript code from within your NVO.
If you like, feel free to send me an email (see my profile for my email address), I'd be interested in exchanging ideas about how to do this.
I didn't use PowerBuilder for a while but I guess that the problem that you are trying to solve is similar to the one I am trying to address for people making projects with SCADA systems like Wonderware Intouch.
The problem with such an application is that there is no API to get or set the value of a control. So a pywinauto approach can't work.
I've made a small tool to simulate the user events and to get the results from a screencapture. I am usig PIL and pytesser ORM for the analysis of the screen captures. It is not the easiest way but it works OK.
The tool is open-source and free of charge and can be downloaded from my website (Sorry in french). You just need an account but it's free as well. Just ask.
If you can read french, here is one article about testing Intouch-based applications
Sorry for the self promotion, but I was facing a similar problem with no solution so I've written my own. Anyway, that's free and open-source...
I've seen in AutomatedQa support that they a recipe recommending using msaa and setting some properties on the controls. I do not know if it works.
If you are testing DataWindows (the class is pbdwxxx, e.g. pbdw110) you will have to use a combination of clicking at specific coordinates and sending Tab keys to get to the control you want. Of course you can also send up and down arrow keys to move among rows. The easiest thing to do is to start with a normal control like an SLE and tab into the DataWindow. The problem is that the DataWindow is essentially just an image. There is no control for a given field until you move the focus there by clicking or tabbing. I've also found that the DataWindow's iAccessible interface is a bit strange. If you ask the DataWindow for the object with focus, you don't get the right answer. If you enumerate through all of the children you can find the one that has focus. If you can modify the source I also advise that you set AccessibleName for your DataWindow controls, otherwise you probably won't be able to identify the controls except by position (by DataWindow controls I mean the ones inside the DataWindow, not the DataWindow itself). If it's an MDI application, you may also find it useful to locate the MicroHelp window (class fnhelpxxx, e.g. fnhelp110, find from the main application window) to help determine your current context.
Edited to add:
Sikuli looks very promising for testing PowerBuilder. It works by recognizing objects on the screen from a saved fragment of screenshot. That is, you take a screenshot of the part of the screen you want it to find.