-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[MAINT] Remove redundancy in Abtract Qt Classes #10779
Comments
It seems very not DRY because, for instance, |
Oh I see because you can call |
Maybe I need to dwell on this and see if I warm up to it, but this method of abstraction in #10565 seems terribly confusing to me. When you call I think the best solution is more toward the first one, otherwise it's going to be impossible to keep track of all the attributes that are created behind the scenes in the abstract classes and obviously the layout had to be returned because you can have more than 1 of them. You probably don't want more than one toolbar but to me a toolbar and a status bar are pretty arbitrary distinctions and the more general, powerful abstraction is that of a bar which can be top, bottom or either side and potentially doubled up (I was considering a spectogram bar above the toolbar for a vertical layout). In summary, a big -1 from me on the direction that this is going although I do think it's salvageable as long as everything gets returned from the abstract classes and then you can interact with abstract object methods that are documented in the abstract class like |
I am wary of a huge refactoring because stuff almost always breaks. But if in the end it makes things more understandable and maintainable, it could be worth it. But the risk of potential additional breakage is high, especially since GUI stuff is very difficult to test with unit tests rather than direct manual interaction / use. +1 for dwelling on it a bit and waiting -- it's always a challenge to understand someone else's code and why they made some choices. You've already started out thinking "this naming scheme doesn't any sense" but realized quickly why it had to be that way (due to how the subclasses are actually used). Let's hold off on a big refactor until you've used the code a bit and understand it through experience a bit. Especially because...
... this whole abstraction came about precisely because we wanted to use it in So I would say let's wait until you need something new from the classes, then add it and get it working. Once that's done, if you still think things could be clearer, a refactoring is much more likely to go smoothly because you have direct experience modifying/improving/fixing bugs with the existing structure. |
Yeah it's definitely in the
The issue with that is that as soon as you stop running things through |
Yes, and
I could see it going either way, and really I don't think it makes a huge difference either way, does it? Typically you only create a toolbar (or don't), and a statusbar (or don't). Thinking of these abstractly as "things around the sides" doesn't seem that helpful as an abstraction to actually implement, even if it's true of where they typically are.
I guess, but typically in practice they are constructed by end users to direct calls to add/create QToolBar and add/create QStatusBar, not via some abstract class. So I'm not sure that Qt having them under the hood implemented as subclasses of a Bar or something really matters/helps us, does it? If it doesn't help us in some way, then we shouldn't bother implementing that deeper level of abstraction.
Yes this is the maintainable idea I think
Indeed, the price we pay for this abstraction is that, instead of just using Qt directly, we need to create an abstraction for whatever new feature we need. This needs to be implemented and tested both places. To me the tradeoff so far has been worth it to have Notebook + Qt support in Brain and coreg.
Maybe this particular implementation isn't perfect or easily understandable. But in the end it should make things simpler, assuming we want to support both Qt and Notebook in MNE-Python, and if we ever want to support one for any GUI. You understand the abstraction and you get the backend flexibility. The cost is that enhancements to the abstraction require implementation and testing at all levels. So to me it sounds like you are arguing two points: first is that our abstraction is unclear, or not implemented as cleanly as it could be -- and this is entirely possible. But we've covered that above (sure let's change it, but hopefully later). The second, though, seems to be that the abstraction is not useful, or that we shouldn't use it for the iEEG GUI. This part I think makes MNE-Python less maintainable in the long run, because instead of having to understand, implement, and test Qt in one place (our abstraction), we have to do so in two places (the iEEG GUI code and our abstraction). |
I think the abstraction is very useful, just think the things that were done for |
Also is there not a tutorial for the |
Hmm... you keep saying "just coreg", so somehow you must have missed the couple of times I've mentioned so far that it's used for Brain, too (and thus stc.plot, etc.). IIRC this is actually where it started, even though that's more a historical point:
So the idea has always been IIUC to have this abstraction and use it across MNE-Python wherever possible. Hence why I'm pushing back on the idea of scrapping what we already have and starting from scratch. We already have an abstraction that works decently even if it's not perfect, or ideally implemented. But maybe others have opinions on this point. FWIW to me the |
Please search first, I seem to recall that there are already one or two issues about |
I need to look more into the The importance of returning the objects for things like status and toolbars is that then they can be modified in inherited objects (i.e. adding items to the toolbar) which seems pretty important. I think that would be one of the main things. EDIT: Reading your last comment more closely, I don't think we need to scrap the whole thing and start from scratch but all the toolbar code that led to the origination of this issue should really be examined. |
After thinking about it, the main issue comes from the Qt concept of a window vs no window for notebook as Guillaume had mentioned. I still think you need a holder, I'll just have to see how Render implements it. This abstraction should work for GUIs without a 3D component but right now it doesn't because of this issue. |
Ok after looking more closely at both the Hopefully the solution is to just make an |
@alexrockhill it sounds like your plan here is to start from scratch / start over, is that right? I am pretty opposed to this idea as it loses / discards all the progress we have made so far by testing and using the existing framework over the last year or two.
A faster and hopefully easier solution (rather than starting an opposing/replacement implementation from scratch) would be the incremental addition of something like
So the only new code is really (2). At least conceptually this makes sense. There are probably bigger but still incremental refactorings we could do, too, but I'd probably save that for later. For one example, we could:
But for any refactoring this big or bigger, I think it's critical before deciding what to do or beginning work that we have some visual depiction (ASCII art, graphviz, powerpoint, whatever) of 1) what we have now, and 2) what the proposed change is. I think it will really help guide things here, and seems like necessary due diligence for any larger change. |
I think we're actually saying very close to the same thing, and I agree about talking about it more before writing code. Whether it's moving the 3D code out of I don't know about making new art or diagrams, I would just propose following more closely to what is done in Qt. I think I need to look into I'm not in favor of a |
It's nothing fancy, probably 10-20 minutes of work (easy) once you understand the actual hierarchy (hard). But understanding the existing hierarchy (the hard part) I think is a prerequisite here... Here are a couple of simple examples you could work from
I really think it would help both the implementation and review stages. (1) and (2) would even be super helpful for maintenance. Just think about how such a thing could have helped you when looking at the code the first time... |
Okay, I think that was pretty helpful, a lot of it is flat (not inherited) but it's nice to enumerate the functionality. I think the main thing is just making use of the |
Just a little to do note for fixing this issue, it's not going to be done today but I don't think it's going to take that long actually, mostly just bookkeeping. Abstract classes that need to be fixed:
Methods that already inherit so that they are not redundant and so are much easier to use 👍
|
E.g. here https://github.com/mne-tools/mne-python/blob/main/mne/viz/backends/_abstract.py#L491. Why do methods of a Qt abstract object have the name of the object in them? i.e.
seems very redundant when
seems like it will do and will be much easier to maintain.
Maybe @larsoner, you have thoughts on this/a good reason for why it is this way?
The text was updated successfully, but these errors were encountered: