python3 tkinter: can I get ragged grids without aligned columns? - python-3.x

I'm writing a GUI in python, and using tkinter. I'm having trouble settling on an approach and need guidance.
Background: there's a server (not a webserver) that wants to present a lot of information to users, and let them edit some of it. It needs to send down information that a (relatvely) dumb python client uses to fill the window. Read only fields are Labels. The fields are generally single line Entry widgets, but some are multiline Text. There are some buttons, checkboxes and dropdowns. Asynchronously, the server can also update widgets, add them and remove them. In some cases, there are tables presented, to which the user needs to be able to add and remove rows.
The real problem is, the layout is dense and chaotic. The first row might contain 3 dropdown fields. The next might be 20 short Labels. The next might be a single long Entry field, and then I might want two tables (of different lengths) side by side,and then etc.. Based on user input of external factors, widgets, rows or entire tables might have to be dyamically added, or vanish.
I considered Grid, but it's unusable. A row with a single, long entry widgit in it, makes the first column wide and thereby pushes 12 of the 13 columns in the next row right off the window.
I considered Place, but this app will run on 3 different operating systems and users will be able to select their own fonts, so I'll never get the positions right. If there was some way to ask a widget how big it was, I'd happily use that to compute my own layouts in pixels, but it's apparently impossible to ask the size of a widget until AFTER it's been laid out by a geometry manager, which of course is too late.
So what I think I'm left with is Pack, where each row is its own frame, and some of those rows have tables (grids) in them. But I'm concerned that that means lots and lots of frames to render, and some of the users are on old, slow hardware. Plus... it looks just plain complex.
Am I missing a better way? Grid would be fine if I could convince it to stop trying to make columns line up. Place would be crunchy, but ok, if I could get the size of each widget in advance. Is placing within a lot of frames really the best I have?

Short answer, there's no better way; and the frame count isn't high enough to cause performance problems; so generating a frame per row is what works.

Related

Open multiple positions in Backtrader

Does someone know if it's possible to open multiple positions with only a single data feed? I am trying to do a second buy whilst in a position, which doesn't seem to be possible.
Nobody seems to adress this issue. Does anyone have any experience with Backtrader and have any input?
If you are just trying to buy more stock to add to your position, then yes, you should be able to do this and if you cannot recheck your strategy code in next.
If you are trying to track two separate positions of the same data...
One cannot have two separate positions in the same data feed. You may trade additional positions if you like but they will be combined in Backtrader. Even if you use two strategies you will still have one combined broker.
The reason for this is to simulate as near as possible real world conditions. If you have a brokerage account you most likely would have just one postion. (I know there are exceptions)
One solution would be to track your trading manually in a dictionary trades that result from different signals/sub-strategies. It's a bit more tedious to develop but very doable.

Printing Grid Component

I have a MultiGrid component with a single fixed row. I would like to print the result, but since multiple columns overflow on the x-axis, the print output gets truncated.
Is it possible to wrap each row in another element and then use display table-cell/table-row to get the desired, table-like behavior? The added benefit is that a table can easily stretch the entire page, even if the number of columns is low.
Is it possible to wrap each row in another element
Yes. It would be possible to wrap rows by injecting your own cellRangeRenderer property. That being said, I don't really recommend it. RV doesn't really have "rows" or "columns"- just positioned cells. Wrapping would add extra elements which could slow down scroll performance. (Probably not much, but every little bit counts for scrolling.)
and then use display table-cell/table-row to get the desired,
table-like behavior?
If you're using MultiGrid I assume you have enough columns to warrant windowing horizontal data as well as vertical? In which case, I don't think display:table would really work for you. I'm not sure what it would buy you.
Have you considered just rendering a non-RV layout specifically printing? I Haven't done this myself but maybe you could tap into beforeprint/afterprint and setState to render a different result? Alternately you could try setting overflowColumnCount really high when print mode is enabled to just render the entire horizontal axis.
I don't really have much experience with this unfortunately. It might require a little of experimentation on your part for the best performing solution. :)

Dynamically load/populate data based on scrollbar handle position?

My PyQt application pulls data from third party API calls. The dataset returned usually contains in the neighborhood of hundreds of items. On occasion, the dataset returned contains in the tens of thousands of items. On those occasions, the interface is painfully slow to display - too slow to be useful.
To speed things up, I would like to load less of the data during the initial load. I would like to be able to populate the interface based on the scrollbar handle position. I would prefer that the scrollbar have the correct range as soon as the widget is displayed, but as the user scrolls, the data that they should be seeing is populated into the widget (a QTreeWidget in this case). This is to say that I'd rather the user didn't have to scroll to the bottom of the widget to load more data at the bottom & therefore change the range of the scroll bar.
I believe QSqlTable behaves this way out of the box, but because I'm not relying on sql queries (and because some of the columns' data is calculated by the GUI), I don't believe I can use that module. Is this possible with QTreeWidget and w/o direct sql calls?
There is built-in functionality for this in Qt model-view framework. See QAbstractItemModel.canFetchMore() and QAbstractItemModel.fetchMore() here
Oh, I've just realised you aren't using MVF but stand-alone QTreeWidget instead. If you are dealing with large data and require such a functionality, a switch to MVF may be a right thing to do.

Millions of rows in GUI

I would like to implement a GUI handling a huge number of rows and I need to use GTK in Linux.
I started having a look at GTKTreeView with lists but I don't think that adding millions of lines directly to that widget will help in having a GUI that doesn't slow the application.
Do you know whether there is a GTK widget already in place for this problem or do I have to handle my self the window frame that that must display those lines? Eventually I would write the data directly using GtkDrawingArea (essentially writing a new widget).
Any suggestion about any GTK topic or project I can look as starting point for my research?
As suggested in the comments, you can use the Cell Data Func, and get the displayed data under contro. But I have another idea: Millions of lines are much much more than any amount of information a human user can see and understand. So maybe a better, more usable and user-friendly solution, is to diaplay the data in a way the users can more easily navigate in it.
Imagine opening a huge hierarchy, scrolling down, and forgetting what were the top-level items you opened.
Example for a possible solution: Have a combo box which allows to choose some filter or category, and this can reduce the amount of data to a reasonable amount the user can more easily navigate and make a mental model of it if necessary.
NOTE: As far as I know, GtkTreeView doesn't support sorting/filtering and drag-n-drop at the same time, so if you want to use both features, I suggest you use the existing drag-n-drop functionality (otherwise very complicated to implement by hand) and implement your own sorting/filtering.

Organizing Lots of Data in Search Results

I'm working on a pretty basic web app (not much more than CRUD stuff). However, the requirements call for a bunch of data to be displayed with each item in the search results - IDs, dates, email addresses, long descriptions... too much to fit neatly into a simple grid, and too dissimilar to make them flow together (like the natural language example from this article.)
Is there a design pattern for attractively displaying many descriptive fields with each search result?
(Please don't tell me to just remove some fields from the results; that's not an option for this project.)
Obviously there are many ways you can handle this, and to a degree it's a factor of your information design abilities and preferences.
Natural Data Groupings
What I would do is try to organize your data into a small number of "buckets." You state that the data are too dissimilar to be arranged into a sentence, but it's likely you can create a few logical groups. Since we can't see all your data, I'll guess that you have information about a person (email, name, ID?), about some sort of event (dates? type?), or maybe about some kind of object related to the person (orders? classes?). Whatever they are, some of the data will be more closely related to each other than others.
Designing in Chunks
Take each loose "bucket" and design a kind of "plate" -- a grouping just for the information in that bucket. The design problem within this constrained chunk is easier to tackle: maybe it's a little table-like layout, maybe it's something non-tabular, like the stackoverflow user "nameplate". Maybe long textual data have their own plates, or maybe they're grouped into a single plate, but with a preview/detail click-for-more arrangement.
Using a Grid
Now that you have a small number of "plates," go back to a grid-like approach for your overall search result row design. Arrange the plates as units within the row, and be sure to keep them aligned. Following an overall grid (HTML table or otherwise) for the plates will avoid an "information soup" problem. You'll have clean columns that scan well, and a readable, natural information hierarchy. The natural language example you cite would indeed be difficult to parse if it were one of many rows displayed in a search results grid.
Consistency
Be sure to use a common "design vocabulary" when you're working on the chunks -- consistent styling of labels, consistent spacing... so when everything's displayed, despite the bulk of information, it all feels like it's part of the same family.
It's an interesting design exercise. Many comps, lots of iteration, and some brainstorming should get you where you need to be.
It probably depends on the content you're displaying. Look at the StackOverflow layout for this question. It has Votes, Title, Description, Tags, Author, etc. The content wouldn't work well in a grid for sure, nor does it flow nicely on it's own.
I think it's time to get creative ;)
No one ever thinks about what this is going to look like on their screen, do they?
One thing you can do is truncate the displayed text, and then display the expanded version in a tooltip on hover, or after the user clicks on it.
For example, display only the two-letter state abbreviation but show the full state name on hover.
Or, to save even more space, only display the state abbreviation, and put the entire address in the tooltip.
For long descriptions, you can display only the first few characters, followed by an ellipsis or the word "More". Then, show the full text either on hover or on click.
One disadvantage of the hover approach is that you can't sort the column on that text. There's nothing for the user to click to request the sort.

Resources