I have to build an application where I have tasks assigned to resources.
I would need to design a kind of Gantt chart where I have a row for each resources (approximately 200) and on each row there are several tasks assigned to the corresponding resource (up to 30 in a month).
I have to move the tasks among the resources in order to reallocate the corresponding task from one resource to an other by using drag and drop.
Also there is an another list of tasks which have not been allocated to a resource, I have to allocate them by drag and drop to a chosen resource.
There is no relationship between the tasks, just simple "boxes" put to the right position (right row and datetime column).
Altogether I have to display around 4000 tasks in a month and being able to move them along, so the performance must be fine.
All the solutions I've seen (matplotlib, python-gantt, etc.) are (as I've understood) just static display of tasks, no dynamic drag and drop interaction.
Are there any ready to use (possible open source) gantt chart type of solution for python I could use for my project?
Related
I'm writing a unit test for a Qt application using the Squish framework. The squish scripting language is Python.
In order to make my test robust, I need to make sure that the GUI has completed an operation before checking the results.
In this GUI, I have a QTableView with an associated model. Certain operations will change the data in the model and the table will update. The update is sequenced internally by Qt.
My issue is that I need to know when the table has completed updating before I check to see whether it has the correct data.
I'm looking for ideas how to do this.
Squish not only views the QTableView GUI surface but will also access the underlying QAbstractItemModel. The data you see in your checks should therefore be live already.
But Qt GUIs are indeed full of asynchronous processing through timers, sometimes threads and signals. If you want to be notified on changes that are accompanied by a signal there's the installSignalHandler() function. If you want to wait for a particular state of to appear there's the waitFor() function. In the case of the table you may want to use
waitFor("mytable.model().rowCount() == 30")
for example.
Say I have data plotted for the last 50 years, but then I want to select last month, last year, last 10yrs, etc. I can do this approximately by using a box zoom tool, but is there a way for easier time series selection beyond box zoom?
For example, a slider bar (like google finance) or a radio button group (to select '1M', '1Y') but I want them to be standalone, not served. They are just an improved easy-to-use version of box zoom.
If you do not want to use the bokeh server, you have to do it on the client side. This can be done by adding custom tools or widgets in coffeescript (which compiles into javascript)
This example shows you the direction to go. I made another custom tool for bokeh and from that experience I would recommend you work on the coffeescript side (instead of writing it directly in javascript) since the javascript part of bokeh is still changing quite a bit between releases, the coffee script way might abstract a bit the detail dependencies of the library.
Currently I am showing a number of user-defined GUI components (templates) (let's give it a name: signal) in some of my main windows. Those GUI components are spread around the windows and are quite a lot in number (>50 per window) and I have multiple of such windows.
I have created all those windows using Ignition GUI and so far they are done... but... Now, there is a requirement to make whatever signal is displayed in the GUI window to be shown in a list of GUI.
My questions are:
How to obtain list of GUI component (template) of the same type (signal) using Ignition Python/Jython Script?
How to get its custom properties (such as customDisplayName)
How to draw the GUI component (template) dynamically?
As of now, it is possible for me to drag and drop components (making exact copy of the displayed signals) in the container list I use to display the signal template. But since it is possible for new signal to be added in the GUI, I am looking for a more automated solution (if there is any).
Ignition supports obtaining of the GUI components by .components from the container type component using Jython script.
So in the end, the implementation of my solution for this question was:
for comp in rootcontainer.components: #looping through every component in the root container
if 'MySignal' in comp.name: #check the name of the component, see if it matches
#do the logic here
I'm developing a GUI with PyQt. The GUI has a qListWidget, a qTableWidget, and a plot implemented with Mayavi. The list refers to shapes that are plotted (cylinders and cones for example). When a shape is selected in the list, I want the shape's properties to be loaded into the table (from a dictionary variable) and the shape to be highlighted in the plot. I've got the Mayavi plotting working fine. Also, if the table is edited, I need the shape to be re-plotted, to reflect the new property value (like for a cylinder, if the radius is changed).
So, when a list item is selected -> update the table with the item's properties (from a dictionary variable), highlight the item on the plot
When the table is edited -> update the dictionary variable and re-plot the item
The Problem: when I select a list item and load data into the table, the qTableWidget ItemChanged signal fires every time a cell is updated, which triggers re-plotting the shape numerous times with incomplete data.
Is there a typical means of disabling the GUI event loop while the table is being programmatically updated? (I have experience with Excel VBA, in that context setting Application.EnableEvents=False will prevent triggering a WorksheetChange event every time a cell is programmatically updated.)
Should I have a "table update in progress" variable to prevent action from being taken while the table is being updated?
Is there a way to update the Table Widget all at once instead of item by item? (I'll admit I'm intentionally avoiding Model-View framework for the moment, hence the qListWIdget and qTableWidget).
Any suggestions?
I'm a first time poster, but a long time user of StackOverflow, so I just want to say thanks in advance for being such an awesome community!
blockSignals(bool) is intended for suppressing QObjects and their subclasses from emitting signals, thus preventing any other objects from receiving them in slots. But this is a QObject method. If you are specifically trying to prevent one object from emitting signals in response to changes that you are making, which might trigger calculations or some other expensive processing in a slot, then this is what you want.
But if your situation is that making repeated changes is causing expensive paint operations over and over (or other expensive events being generated on the widget), then you have the ability to disable updates with updatesEnabled(bool). A benefit of this method is that it recursively disables the children of the target widget, preventing them from being updated as well. So nothing in the hierarchy will receive updates until you enable again.
mainWidget.setUpdatesEnabled(False)
# do a bunch of operations that would trigger expensive events
# like repaints
mainWidget.setUpdatesEnabled(True)
Ultimately it depends on whether the source of your problem comes from triggering signals, or triggering widget events. Blocking the signals will still allow the widget to process its events, but just not notify any other listeners about it. updatesEnabled is a common way to wrap a number of list/table/tree updates. When it is enabled again afterwards, a single post update will be performed.
Signals can be temporarily blocked for any object that inherits QObject:
self.tableWidget.blockSignals(True)
# perform updates, etc
self.tableWidget.blockSignals(False)
If you disable the entire event loop, the app becomes unresponsive. And, even if the user doesn't notice, the OS might, and put up some kind of "hang" notification (like OS X's brightly-colored spinning beachball, which no user will ever miss).
You might want to disable repaints without disabling the event loop entirely. But even that's probably too drastic.
All you're really trying to do is make sure the table stops redrawing itself (without changing the way you've implemented your table view, which you admit isn't ideal, but you have reasons for).
So, just disable the ItemChanged updates. The easiest way to do this, in almost every case, is to call blockSignals(True) on the widget.
In the rare cases where this won't work (or when you're dealing with ancient code that's meant to be used in both Qt4-based and earlier projects), you can still get the handler(s) for the signal, stash them away, and remove them, then do your work, then restore the previous handler(s).
You could instead create a flag that the handlers can access, and change them so they do nothing if the flag is set. This is the traditional C way of doing things, but it's usually not what you want to do in Python.
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. ;-)