Commit 4ee67162 authored by Andoni Jimenez's avatar Andoni Jimenez
Browse files

Refactor bottom widgets (moved to widgets.py)

parent ff292b63
Loading
Loading
Loading
Loading
+16 −165
Original line number Diff line number Diff line
@@ -50,7 +50,8 @@ class Ui(QtWidgets.QMainWindow):
            
        # Import config
        try:
            with open("config", 'r') as f:
            file_config = utils.args.config
            with open(file_config, 'r') as f:
                config:dict = json.loads(f.read())
        except:
            raise
@@ -108,8 +109,10 @@ class Ui(QtWidgets.QMainWindow):
        
        for tconf in config:
            tconf:dict
            cols = 2 # default cols inside each widget
            count = 0 # pointer to current col inside widget
            # cols = 2 # default cols inside each widget
            # count = 0 # pointer to current col inside widget
            # self._cols = cols
            # self._count = count
            try:
                # check basic define params
                if 'id' in tconf.keys():
@@ -126,112 +129,28 @@ class Ui(QtWidgets.QMainWindow):
                # size policy
                if wcount%wcols == 0: # first column
                    wpol = QtWidgets.QSizePolicy(policy.Preferred, policy.Preferred)
                elif wcols-(wcount%wcols) == 1: # last column
                elif wcount%wcols == wcols-1: # last column
                    wpol = QtWidgets.QSizePolicy(policy.Maximum, policy.Preferred)
                else:
                    wpol = QtWidgets.QSizePolicy(policy.Minimum, policy.Preferred)

                gb = newGroupBox(id, name, wpol)
                # COMMENTBOX
                if tconf['type'] == 'text':
                    widget = QtWidgets.QPlainTextEdit(None)
                    widget.setObjectName(f"tb_{id}")
                    widget.setSizePolicy(QtWidgets.QSizePolicy(policy.Expanding, policy.Preferred))
                    addTextBoxTexts(widget, tconf)
                    widget.installEventFilter(self) # Set enter as save
                    
                    gb.layout().addWidget(widget)
                    self.commentBox = widget 
                    self.tb[id] = widget
                    gb = widgets.CommentBox(self, tconf, wpol)
                # CHECKBOX
                elif tconf['type'] == 'checkbox':
                    if 'ncolumns' in tconf.keys():
                        cols = tconf['ncolumns']
                    if 'elements' in tconf and len(tconf['elements']) > 0:
                        self.cb[id] = {}
                        
                    for element in tconf['elements']:
                        try:
                            eid = element['id']
                            wid = f"cb_{eid}"
                            # add checkbox
                            widget = QtWidgets.QCheckBox(None)
                            widget.setObjectName(wid)
                            widget.setSizePolicy(QtWidgets.QSizePolicy(policy.Minimum, policy.Fixed))
                            addCheckBoxTexts(widget, element)
                            addToolTip(widget, element)
                            
                            gb.layout().addWidget(widget, count//cols, count%cols)
                            count += 1
                            # save widget
                            self.cb[id][eid] = widget
                            # self.cbColumns.append(eid)
                            # self.cbNames.append(wid)
                            
                        except KeyError as e:
                            print(f"KeyError: {e}")
                    gb = widgets.CheckBoxGroup(self, tconf, wpol)
                # RADIOBUTTON TYPE 
                elif tconf['type'] == 'radiobutton':
                    if 'ncolumns' in tconf.keys():
                        cols = tconf['ncolumns']*2 # *2 -> shortcut and name in 2 rows
                    
                    gbb = QtWidgets.QButtonGroup()
                    gbb.setObjectName(f"gbb_{id}")
                    
                    if 'elements' in tconf and len(tconf['elements']) > 0:
                        self.rb[id] = {}
                    for element in tconf['elements']:
                        element:dict
                        try:
                            eid = element['id']
                            wid = f"rb_{eid}"
                            # radiobutton
                            widget = QtWidgets.QRadioButton(None)
                            widget.setObjectName(wid)
                            widget.setSizePolicy(QtWidgets.QSizePolicy(policy.Minimum, policy.Fixed))
                            addRadioButtonTexts(widget, element)
                            addToolTip(widget, element)
                            
                            gbb.addButton(widget)
                            gb.layout().addWidget(widget, count//cols, count%cols)
                            count += 1
                            # save widget
                            self.rb[id][eid] = widget
                            # self.rbTypes.append(eid)
                            # self.rbNames.append(wid)
                            
                            # shortcut label
                            if 'shortcut' in element.keys():
                                widget = QtWidgets.QLabel(None)
                                widget.setSizePolicy(QtWidgets.QSizePolicy(policy.Preferred, policy.Preferred))
                                widget.setText(f"[{element['shortcut']}]")
                                gb.layout().addWidget(widget, count//cols, count%cols)
                            count += 1
                        except KeyError as e:
                            print(f"KeyError: {e}")
                    if 'add_clear' in tconf.keys() and tconf['add_clear'] is True:
                        widget = QtWidgets.QPushButton(None)
                        widget.setObjectName(f"pb_clear_{id}")
                        widget.setSizePolicy(QtWidgets.QSizePolicy(policy.Minimum, policy.Fixed))
                        
                        text = f"Clear"
                        if 'clear_shortcut' in tconf.keys():
                            text += f" [{tconf['clear_shortcut']}]"
                        widget.setText(text)
                        widget.clicked.connect(lambda: self.clear_ButtonGroup(gbb))
                        gb.layout().addWidget(widget, count//cols, count%cols, 1, cols)

                    self.rbg[id] = gbb
                    gb = widgets.RadioButtonGroup(self, tconf, wpol)
                else:
                    print(f"{tconf['type']} not implemented")

                # gb_img.layout().addWidget(gb, wcount//wcols, wcount%wcols)
                frame.layout().addWidget(gb, wcount//wcols, wcount%wcols)
                wcount += 1
            except:
                raise

        
        # Dynamic COLUMNS
        utils.IDS['FILE'] = list(df.columns)
        
@@ -487,7 +406,8 @@ class Ui(QtWidgets.QMainWindow):
            
            # radiobuttons
            for id, bg in self.rbg.items():
                self.clear_ButtonGroup(bg)
                bg.clear_ButtonGroup()
                # self.clear_ButtonGroup(bg)
                selected = item[id].item()
                if selected in self.rb[id].keys():
                    # idChecked = self.rbNames[self.rbTypes.index(selected)] # refactor rbTypes and rbNames?
@@ -545,16 +465,6 @@ class Ui(QtWidgets.QMainWindow):
        self.fileList.selectRow(index-1)

    
    def clear_ButtonGroup(self, bg:QtWidgets.QButtonGroup) -> None:
        # for i, cb in enumerate(self.rbNames):
        #     self.rb[self.rbTypes[i]].setAutoExclusive(False)
        #     self.rb[self.rbTypes[i]].setChecked(False)
        #     self.rb[self.rbTypes[i]].setAutoExclusive(True)
        if bg.checkedButton() is not None:
            bg.setExclusive(False)
            bg.checkedButton().setChecked(False)
            bg.setExclusive(True)
    
    # Actions helpers

    def exit(self) -> None:
@@ -648,62 +558,3 @@ class Ui(QtWidgets.QMainWindow):
    def splitterResizeEvent(self, pos, index) -> None:
        # Re-draw image:
        self.showImage(self.imgPath)


# Widget ops
def newGroupBox(id:str, name:str, policy:QtWidgets.QSizePolicy) -> QtWidgets.QGroupBox:
    gb = QtWidgets.QGroupBox(name)
    gb.setObjectName(f"gb_{id}")
    gb.setSizePolicy(policy)
    #gb.setMinimumSize(50, 150)
    gb.setLayout(QtWidgets.QGridLayout())
    return gb

def addToolTip(widget: QtWidgets.QWidget, element:dict) -> None:
    try:
        widget.setToolTip(f"{element['description']}")
    except KeyError as e:
        print(f"KeyError: {e}")
        
def addTextBoxTexts(widget: QtWidgets.QPlainTextEdit, element:dict) -> None:
    shortcut = None
    try:
        shortcut = element['shortcut']
    except KeyError as e:
        print(f"KeyError: {e}")
    finally:
        if shortcut is None:
            widget.setPlaceholderText(f"Press [Enter] to save, and [Esc] to discard.")
        else:
            widget.setPlaceholderText(f"Press [{shortcut}] to insert comments. Press [Enter] to save, and [Esc] to discard.")
            # add shortcut 
            ws = QtWidgets.QShortcut(shortcut, widget)
            ws.activated.connect(widget.setFocus)

def addCheckBoxTexts(widget: QtWidgets.QCheckBox, element:dict) -> None:
    id, name, shortcut = None, None, None
    try:
        id, name, shortcut = element['id'], element['name'], element['shortcut']
    except KeyError as e:
        if name is None:
            name = id.capitalize()
        print(f"KeyError: {e}")
    finally:
        if shortcut is None:
            widget.setText(name)
        else:
            widget.setText(f"[{shortcut}] {name}")
            widget.setShortcut(shortcut)
        
def addRadioButtonTexts(widget: QtWidgets.QRadioButton, element:dict) -> None:
    id, name, shortcut = None, None, None
    try:
        id, name, shortcut = element['id'], element['name'], element['shortcut']
    except KeyError as e:
        if name is None:
            name = id.capitalize()
        print(f"KeyError: {e}")
    finally:
        widget.setText(name)
        if shortcut is not None:
            widget.setShortcut(shortcut)
 No newline at end of file
+228 −2
Original line number Diff line number Diff line
from PyQt5 import QtWidgets
import typing
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtCore import Qt
import pandas as pd
import numpy as np
@@ -156,3 +157,228 @@ class StaticImage(QtWidgets.QLabel):
        w = self.width()
        h = self.height()
        self.setPixmap(pixmap.scaled(w, h, Qt.KeepAspectRatio, Qt.SmoothTransformation))
   

class BaseWidgetGroup(QtWidgets.QGroupBox):
        
    def __init__(self, wconf:dict, wpolicy:QtWidgets.QSizePolicy) -> QtWidgets.QGroupBox:
        cols = 2 # default cols inside each widget
        count = 0 # pointer to current col inside widget
        
        if 'id' not in wconf.keys():
            raise KeyError('id is mandatory')
        # check basic define params
        
        id:str = wconf['id']

        name = id.capitalize()
        if 'name' in wconf.keys():
            name:str = wconf['name']
            
        # if 'type' not in wconf.keys():
        #     print(f"type of {id}:{name} not specified")
        #     continue
        
        # # size policy
        # if wcount%wcols == 0: # first column
        #     wpol = QtWidgets.QSizePolicy(policy.Preferred, policy.Preferred)
        # elif wcols-(wcount%wcols) == 1: # last column
        #     wpol = QtWidgets.QSizePolicy(policy.Maximum, policy.Preferred)
        # else:
        #     wpol = QtWidgets.QSizePolicy(policy.Minimum, policy.Preferred)
        
        super(BaseWidgetGroup, self).__init__(name)
        
        self.setObjectName(f"gb_{id}")
        self.setSizePolicy(wpolicy)
        #gb.setMinimumSize(50, 150)
        self.setLayout(QtWidgets.QGridLayout())
        
        self._id = id
        self._cols = cols
        self._count = count
        
        
    def addToolTip(self, widget: QtWidgets.QWidget, element:dict) -> None:
        try:
            widget.setToolTip(f"{element['description']}")
        except KeyError as e:
            print(f"KeyError: {e}")
            
    def addTexts(widget:any, element:dict) -> None:
        Warning("Implemented in each child")
        
class CheckBoxGroup(BaseWidgetGroup):
    
    def __init__(self, parent,  wconf:dict, wpolicy:QtWidgets.QSizePolicy, *args, **kwargs):
        super(CheckBoxGroup, self).__init__(wconf, wpolicy, *args, **kwargs)
        
        cols = self._cols
        count = self._count
        
        if 'ncolumns' in wconf.keys():
            cols = wconf['ncolumns']
            
        id = self._id
        if 'elements' in wconf and len(wconf['elements']) > 0:
            parent.cb[id] = {}
            
        for element in wconf['elements']:
            try:
                eid = element['id']
                wid = f"cb_{eid}"
                # add checkbox
                widget = QtWidgets.QCheckBox(None)
                widget.setObjectName(wid)
                widget.setSizePolicy(QtWidgets.QSizePolicy(policy.Minimum, policy.Fixed))
                self.addTexts(widget, element)
                self.addToolTip(widget, element)
                
                self.layout().addWidget(widget, count//cols, count%cols)
                count += 1
                # save widget
                parent.cb[id][eid] = widget
                # self.cbColumns.append(eid)
                # self.cbNames.append(wid)
                
            except KeyError as e:
                print(f"KeyError: {e}")
    
    def addTexts(self, widget: QtWidgets.QCheckBox, element:dict) -> None:
        id, name, shortcut = None, None, None
        try:
            id, name, shortcut = element['id'], element['name'], element['shortcut']
        except KeyError as e:
            if name is None:
                name = id.capitalize()
            print(f"KeyError: {e}")
        finally:
            if shortcut is None:
                widget.setText(name)
            else:
                widget.setText(f"[{shortcut}] {name}")
                widget.setShortcut(shortcut)


class CustomButtonGroup(QtWidgets.QButtonGroup):
        def __init__(self, id) -> None:
            super().__init__()
            self.setObjectName(f"gbb_{id}")

        def clear_ButtonGroup(self) -> None:
            if self.checkedButton() is not None:
                self.setExclusive(False)
                self.checkedButton().setChecked(False)
                self.setExclusive(True)


class RadioButtonGroup(BaseWidgetGroup):
       
    def __init__(self, parent,  wconf:dict, wpolicy:QtWidgets.QSizePolicy, *args, **kwargs):
        super(RadioButtonGroup, self).__init__(wconf, wpolicy, *args, **kwargs)
        
        cols = self._cols
        count = self._count
        
        if 'ncolumns' in wconf.keys():
            cols = wconf['ncolumns']*2 # *2 -> shortcut and name in 2 rows
        
        id = self._id
        gbb = CustomButtonGroup(id)
        
        if 'elements' in wconf and len(wconf['elements']) > 0:
            parent.rb[id] = {}
        for element in wconf['elements']:
            element:dict
            try:
                eid = element['id']
                wid = f"rb_{eid}"
                # radiobutton
                widget = QtWidgets.QRadioButton(None)
                widget.setObjectName(wid)
                widget.setSizePolicy(QtWidgets.QSizePolicy(policy.Minimum, policy.Fixed))
                self.addTexts(widget, element)
                self.addToolTip(widget, element)
                
                gbb.addButton(widget)
                self.layout().addWidget(widget, count//cols, count%cols)
                count += 1
                # save widget
                parent.rb[id][eid] = widget
                # self.rbTypes.append(eid)
                # self.rbNames.append(wid)
                
                # shortcut label
                if 'shortcut' in element.keys():
                    widget = QtWidgets.QLabel(None)
                    widget.setSizePolicy(QtWidgets.QSizePolicy(policy.Preferred, policy.Preferred))
                    widget.setText(f"[{element['shortcut']}]")
                    self.layout().addWidget(widget, count//cols, count%cols)
                count += 1
            except KeyError as e:
                print(f"KeyError: {e}")
                
        if 'add_clear' in wconf.keys() and wconf['add_clear'] is True:
            widget = QtWidgets.QPushButton(None)
            widget.setObjectName(f"pb_clear_{id}")
            widget.setSizePolicy(QtWidgets.QSizePolicy(policy.Minimum, policy.Fixed))
            
            text = f"Clear"
            if 'clear_shortcut' in wconf.keys():
                shortcut = wconf['clear_shortcut']
                text += f" [{shortcut}]"
            widget.setText(text)
            if shortcut is not None:
                widget.setShortcut(shortcut)
            widget.clicked.connect(gbb.clear_ButtonGroup)
            self.layout().addWidget(widget, count//cols, count%cols, 1, cols)

        parent.rbg[id] = gbb
        
    
    def addTexts(self, widget: QtWidgets.QRadioButton, element:dict) -> None:
        id, name, shortcut = None, None, None
        try:
            id, name, shortcut = element['id'], element['name'], element['shortcut']
        except KeyError as e:
            if name is None:
                name = id.capitalize()
            print(f"KeyError: {e}")
        finally:
            widget.setText(name)
            if shortcut is not None:
                widget.setShortcut(shortcut)


class CommentBox(BaseWidgetGroup):
    
    def __init__(self, parent,  wconf:dict, wpolicy:QtWidgets.QSizePolicy, *args, **kwargs):
        super(CommentBox, self).__init__(wconf, wpolicy, *args, **kwargs)                
        
        # configure internal widget
        widget = QtWidgets.QPlainTextEdit(None)
        widget.setObjectName(f"tb_{self._id}")
        widget.setSizePolicy(QtWidgets.QSizePolicy(policy.Expanding, policy.Preferred))
        
        self.addTexts(widget, wconf)
        widget.installEventFilter(parent) # Set enter as save
                    
        self.layout().addWidget(widget)
        # add to parents textbox list
        parent.tb[self._id] = widget
        
    
    def addTexts(self, widget: QtWidgets.QPlainTextEdit, element:dict) -> None:
        shortcut = None
        try:
            shortcut = element['shortcut']
        except KeyError as e:
            print(f"KeyError: {e}")
        finally:
            if shortcut is None:
                widget.setPlaceholderText(f"Press [Enter] to save, and [Esc] to discard.")
            else:
                widget.setPlaceholderText(f"Press [{shortcut}] to insert comments. Press [Enter] to save, and [Esc] to discard.")
                # add shortcut 
                ws = QtWidgets.QShortcut(shortcut, widget)
                ws.activated.connect(widget.setFocus)
 No newline at end of file