Skip to content

Commit

Permalink
- limit visible items of device type popups and statistic types
Browse files Browse the repository at this point in the history
- pip upgrade of requirements-dev.txt in GitHub Actions
- lib updates
  • Loading branch information
MAKOMO committed Sep 24, 2024
1 parent 50dc3b3 commit 8d7bf05
Show file tree
Hide file tree
Showing 10 changed files with 62 additions and 37 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/mypy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ jobs:
- name: Install dependencies
run: |
pip install --upgrade pip==24.0 # downgrade pip as pip v24.1 fails with pip._vendor.packaging.version.InvalidVersion: Invalid version: '6.5.0-1022-azure' (image name!)
pip install -r src/requirements-dev.txt
pip install --upgrade -r src/requirements-dev.txt
pip install -r src/requirements.txt
- uses: tsuyoshicho/action-mypy@v4
with:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pylint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ jobs:
- name: Install dependencies
run: |
pip install --upgrade pip==24.0 # downgrade pip as pip v24.1 fails with pip._vendor.packaging.version.InvalidVersion: Invalid version: '6.5.0-1022-azure' (image name!)
pip install -r src/requirements-dev.txt
pip install --upgrade -r src/requirements-dev.txt
pip install -r src/requirements.txt
- name: Analysing the code with pylint
env:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pytest.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ jobs:
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r src/requirements-dev.txt
pip install --upgrade -r src/requirements-dev.txt
pip install -r src/requirements.txt
- name: Test with pytest
run: |
Expand Down
46 changes: 26 additions & 20 deletions src/artisanlib/devices.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@

from artisanlib.util import deltaLabelUTF8, setDeviceDebugLogLevel, argb_colorname2rgba_colorname, rgba_colorname2argb_colorname
from artisanlib.dialogs import ArtisanResizeablDialog
from artisanlib.widgets import MyQComboBox, MyQDoubleSpinBox
from artisanlib.widgets import MyContentLimitedQComboBox, MyQComboBox, MyQDoubleSpinBox


_log: Final[logging.Logger] = logging.getLogger(__name__)
Expand All @@ -39,14 +39,14 @@
from PyQt6.QtWidgets import (QApplication, QWidget, QCheckBox, QVBoxLayout, QHBoxLayout, QLabel, QLineEdit, # @UnusedImport @Reimport @UnresolvedImport
QPushButton, QSpinBox, QTabWidget, QComboBox, QDialogButtonBox, QGridLayout, # @UnusedImport @Reimport @UnresolvedImport
QGroupBox, QRadioButton, # @UnusedImport @Reimport @UnresolvedImport
QTableWidget, QMessageBox, QHeaderView, QTableWidgetItem) # @UnusedImport @Reimport @UnresolvedImport
QTableWidget, QMessageBox, QHeaderView, QTableWidgetItem, QSizePolicy) # @UnusedImport @Reimport @UnresolvedImport
except ImportError:
from PyQt5.QtCore import (Qt, pyqtSlot, QSettings, QTimer, QRegularExpression) # type: ignore # @UnusedImport @Reimport @UnresolvedImport
from PyQt5.QtGui import (QStandardItemModel, QStandardItem, QColor, QIntValidator, QRegularExpressionValidator) # type: ignore # @UnusedImport @Reimport @UnresolvedImport
from PyQt5.QtWidgets import (QApplication, QWidget, QCheckBox, QVBoxLayout, QHBoxLayout, QLabel, QLineEdit, # type: ignore # @UnusedImport @Reimport @UnresolvedImport
QPushButton, QSpinBox, QTabWidget, QComboBox, QDialogButtonBox, QGridLayout, # @UnusedImport @Reimport @UnresolvedImport
QGroupBox, QRadioButton, # @UnusedImport @Reimport @UnresolvedImport
QTableWidget, QMessageBox, QHeaderView, QTableWidgetItem) # @UnusedImport @Reimport @UnresolvedImport
QTableWidget, QMessageBox, QHeaderView, QTableWidgetItem, QSizePolicy) # @UnusedImport @Reimport @UnresolvedImport


class DeviceAssignmentDlg(ArtisanResizeablDialog):
Expand Down Expand Up @@ -122,7 +122,7 @@ def __init__(self, parent:QWidget, aw:'ApplicationWindow', activeTab:int = 0) ->
dev.pop(i) #note: pop() makes the list smaller that's why there are 2 FOR statements
break
self.sorted_devices = sorted(dev)
self.devicetypeComboBox = MyQComboBox()
self.devicetypeComboBox = MyContentLimitedQComboBox()

## self.devicetypeComboBox.setSizeAdjustPolicy(QComboBox.SizeAdjustPolicy.AdjustToContents)
## self.devicetypeComboBox.view().setTextElideMode(Qt.TextElideMode.ElideNone)
Expand Down Expand Up @@ -1002,6 +1002,9 @@ def __init__(self, parent:QWidget, aw:'ApplicationWindow', activeTab:int = 0) ->
self.yoctoBoxRemoteFlag.stateChanged.connect(self.yoctoBoxRemoteFlagStateChanged)
yoctoServerIdLabel = QLabel(QApplication.translate('Label','VirtualHub'))
self.yoctoServerId = QLineEdit(self.aw.qmc.yoctoServerID)
self.yoctoServerId.setAlignment(Qt.AlignmentFlag.AlignRight)
self.yoctoServerId.setMinimumWidth(100)
self.yoctoServerId.setSizePolicy(QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Minimum)
self.yoctoServerId.setEnabled(self.aw.qmc.yoctoRemoteFlag)
YoctoEmissivityLabel = QLabel(QApplication.translate('Label','Emissivity'))
self.yoctoEmissivitySpinBox = MyQDoubleSpinBox()
Expand All @@ -1013,6 +1016,7 @@ def __init__(self, parent:QWidget, aw:'ApplicationWindow', activeTab:int = 0) ->
yoctoServerBox.addWidget(yoctoServerIdLabel)
yoctoServerBox.addSpacing(10)
yoctoServerBox.addWidget(self.yoctoServerId)
yoctoServerBox.addStretch()
yoctoServerBox.setContentsMargins(0,0,0,0)
yoctoServerBox.setSpacing(10)
yoctoNetworkGrid = QGridLayout()
Expand Down Expand Up @@ -1611,6 +1615,7 @@ def createDeviceTable(self) -> None:
if vheader is not None:
vheader.setSectionResizeMode(QHeaderView.ResizeMode.Fixed)

fixed_size_sections = [7,8,9,10,11,12,13,14]
if nddevices:
dev = self.aw.qmc.devices[:] #deep copy
limit = len(dev)
Expand All @@ -1623,7 +1628,7 @@ def createDeviceTable(self) -> None:
for i in range(nddevices):
try:
# 0: device type
typeComboBox = MyQComboBox()
typeComboBox = MyContentLimitedQComboBox()
# typeComboBox.setSizeAdjustPolicy(QComboBox.SizeAdjustPolicy.AdjustToContentsOnFirstShow) # default
typeComboBox.setSizeAdjustPolicy(QComboBox.SizeAdjustPolicy.AdjustToMinimumContentsLengthWithIcon)
# typeComboBox.setSizeAdjustPolicy(QComboBox.SizeAdjustPolicy.AdjustToContents)
Expand Down Expand Up @@ -1742,28 +1747,29 @@ def createDeviceTable(self) -> None:

except Exception as e: # pylint: disable=broad-except
_log.exception(e)
fixed_size_sections = [7,8,9,10,11,12,13,14]
header = self.devicetable.horizontalHeader()
if header is not None:
header.setStretchLastSection(False)
self.devicetable.resizeColumnsToContents()
for i in fixed_size_sections:
header.setSectionResizeMode(i, QHeaderView.ResizeMode.Fixed)
header.resizeSection(i, header.sectionSize(i) + 5)
if not self.aw.qmc.devicetablecolumnwidths:
self.devicetable.setColumnWidth(0, 100)
self.devicetable.setColumnWidth(3, 100)
self.devicetable.setColumnWidth(4, 100)
self.devicetable.setColumnWidth(5, 40)
self.devicetable.setColumnWidth(6, 40)
else:
# remember the columnwidth
for i, _ in enumerate(self.aw.qmc.devicetablecolumnwidths):
if i not in fixed_size_sections:
try:
self.devicetable.setColumnWidth(i, self.aw.qmc.devicetablecolumnwidths[i])
except Exception: # pylint: disable=broad-except
pass
if not self.aw.qmc.devicetablecolumnwidths:
self.devicetable.setColumnWidth(0, 230)
self.devicetable.setColumnWidth(1, 80)
self.devicetable.setColumnWidth(2, 80)
self.devicetable.setColumnWidth(3, 80)
self.devicetable.setColumnWidth(4, 80)
self.devicetable.setColumnWidth(5, 40)
self.devicetable.setColumnWidth(6, 40)
else:
# remember the columnwidth
for i, _ in enumerate(self.aw.qmc.devicetablecolumnwidths):
if i not in fixed_size_sections:
try:
self.devicetable.setColumnWidth(i, self.aw.qmc.devicetablecolumnwidths[i])
except Exception: # pylint: disable=broad-except
pass
except Exception as e: # pylint: disable=broad-except
_t, _e, exc_tb = sys.exc_info()
self.aw.qmc.adderror((QApplication.translate('Error Message', 'Exception:') + ' createDeviceTable(): {0}').format(str(e)),getattr(exc_tb, 'tb_lineno', '?'))
Expand Down
14 changes: 12 additions & 2 deletions src/artisanlib/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@
QInputDialog, QGroupBox, QLineEdit, # @Reimport @UnresolvedImport @UnusedImport
QSizePolicy, QVBoxLayout, QHBoxLayout, QPushButton, # @Reimport @UnresolvedImport @UnusedImport
QLCDNumber, QSpinBox, QComboBox, # @Reimport @UnresolvedImport @UnusedImport
QSlider, # @Reimport @UnresolvedImport @UnusedImport
QSlider, QProxyStyle, QStyle, QStyleOption, QStyleHintReturn, # @Reimport @UnresolvedImport @UnusedImport
QColorDialog, QFrame, QScrollArea, QProgressDialog, # @Reimport @UnresolvedImport @UnusedImport
QStyleFactory, QMenu, QLayout) # @Reimport @UnresolvedImport @UnusedImport
from PyQt6.QtGui import (QScreen, QPageLayout, QAction, QImageReader, QWindow, # @Reimport @UnresolvedImport @UnusedImport
Expand All @@ -144,7 +144,7 @@
QInputDialog, QGroupBox, QLineEdit, # @Reimport @UnresolvedImport @UnusedImport
QSizePolicy, QVBoxLayout, QHBoxLayout, QPushButton, # @Reimport @UnresolvedImport @UnusedImport
QLCDNumber, QSpinBox, QComboBox, # @Reimport @UnresolvedImport @UnusedImport
QSlider, # @Reimport @UnresolvedImport @UnusedImport
QSlider, QProxyStyle, QStyle, QStyleOption, QStyleHintReturn, # @Reimport @UnresolvedImport @UnusedImport
QColorDialog, QFrame, QScrollArea, QProgressDialog, # @Reimport @UnresolvedImport @UnusedImport
QStyleFactory, QMenu, QLayout, QShortcut) # @Reimport @UnresolvedImport @UnusedImport
from PyQt5.QtGui import (QScreen, QPageLayout, QImageReader, QWindow, # type: ignore # @Reimport @UnresolvedImport @UnusedImport
Expand Down Expand Up @@ -591,6 +591,12 @@ def permissionUpdated(permission:'QPermission') -> None:
# pass


class MenuProxyStyle(QProxyStyle): # pyright: ignore [reportGeneralTypeIssues] # Argument to class must be a base class

def styleHint(self, hint:QStyle.StyleHint, option:Optional[QStyleOption] = None, widget:Optional[QWidget] = None, returnData:Optional[QStyleHintReturn] = None) -> int:
if hint == QStyle.StyleHint.SH_ComboBox_Popup and isinstance(widget, MyContentLimitedQComboBox):
return 0
return QProxyStyle.styleHint(self, hint, option, widget, returnData)


app_args = sys.argv
Expand All @@ -606,6 +612,9 @@ def permissionUpdated(permission:'QPermission') -> None:
# except Exception as e: # pylint: disable=broad-except
# pass
app = Artisan(app_args)
# to limit the number of items displayed in a popup at once we fall back to non-native Qt QComboboxes in MyContentLimitedQComboBox
# by resetting the style hint via a MenuProxy style object
app.setStyle(MenuProxyStyle())


# On the first run if there are legacy settings under "YourQuest" but no new settings under "artisan-scope" then the legacy settings
Expand Down Expand Up @@ -736,6 +745,7 @@ def permissionUpdated(permission:'QPermission') -> None:
from artisanlib.notifications import Notification, NotificationManager, NotificationType
from artisanlib.canvas import tgraphcanvas
from artisanlib.phases_canvas import tphasescanvas
from artisanlib.widgets import MyContentLimitedQComboBox


# import artisan.plus module
Expand Down
13 changes: 6 additions & 7 deletions src/artisanlib/statistics.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@
from typing import Optional, List, Any, cast, TYPE_CHECKING, Final
from artisanlib.dialogs import ArtisanResizeablDialog
from artisanlib.util import deltaLabelUTF8
from artisanlib.widgets import MyQComboBox

from artisanlib.widgets import MyContentLimitedQComboBox
import logging

try:
Expand Down Expand Up @@ -609,7 +608,7 @@ def createSummarystatsTable(self) -> None:

for i in range(nstats):
#0 Type
typeComboBox = MyQComboBox()
typeComboBox = MyContentLimitedQComboBox()
# set the combox width to the full width of the table
typeComboBox.setSizeAdjustPolicy(QComboBox.SizeAdjustPolicy.AdjustToMinimumContentsLengthWithIcon)
typeComboBox.setToolTip(QApplication.translate('Tooltip','Choose a statistic to display'))
Expand Down Expand Up @@ -663,7 +662,7 @@ def copyEventButtonTabletoClipboard(self, _:bool=False) -> None:
rows = []
rows.append(str(r+1))
# type
typeComboBox = cast(MyQComboBox, self.summarystatstable.cellWidget(r,1))
typeComboBox = cast(MyContentLimitedQComboBox, self.summarystatstable.cellWidget(r,1))
rows.append(typeComboBox.currentText())
tbl.add_row(rows)
clipboard = tbl.get_string()
Expand All @@ -678,7 +677,7 @@ def copyEventButtonTabletoClipboard(self, _:bool=False) -> None:
clipboard += '\n'
for r in range(nrows):
clipboard += str(r+1) + '\t'
typeComboBox = cast(MyQComboBox, self.summarystatstable.cellWidget(r,1))
typeComboBox = cast(MyContentLimitedQComboBox, self.summarystatstable.cellWidget(r,1))
clipboard += typeComboBox.currentText() + '\t'
# copy to the system clipboard
sys_clip = QApplication.clipboard()
Expand Down Expand Up @@ -710,15 +709,15 @@ def savetablesummarystats(self, forceRedraw:bool = False) -> None:
def setitemsummarystat(self, _:int) -> None:
i = self.aw.findWidgetsRow(self.summarystatstable,self.sender(),1)
if i is not None:
typecombobox = cast(MyQComboBox, self.summarystatstable.cellWidget(i,1))
typecombobox = cast(MyContentLimitedQComboBox, self.summarystatstable.cellWidget(i,1))
if i < len(self.summarystatstypes):
self.summarystatstypes[i] = self.summarystats_types.index(self.summarystats_types_sorted[typecombobox.currentIndex()])
self.savetablesummarystats()

def disconnectTableItemActions(self) -> None:
for x in range(self.summarystatstable.rowCount()):
try:
typeComboBox = cast(MyQComboBox, self.summarystatstable.cellWidget(x,1))
typeComboBox = cast(MyContentLimitedQComboBox, self.summarystatstable.cellWidget(x,1))
typeComboBox.currentIndexChanged.disconnect() # type combo
except Exception: # pylint: disable=broad-except
pass
Expand Down
9 changes: 9 additions & 0 deletions src/artisanlib/widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,15 @@ def wheelEvent(self, event:'Optional[QWheelEvent]') -> None:
if self.hasFocus():
super().wheelEvent(event)

class MyContentLimitedQComboBox(MyQComboBox): # pylint: disable=too-few-public-methods # pyright: ignore [reportGeneralTypeIssues]# Argument to class must be a base class
def __init__(self, parent:Optional['QWidget'] = None, **kwargs:Dict[Any,Any]) -> None:
super().__init__(parent, **kwargs)
# setting max number visible limit
self.setMaxVisibleItems(20)
view = self.view()
if view is not None:
view.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAsNeeded)

class MyQDoubleSpinBox(QDoubleSpinBox): # pyright: ignore [reportGeneralTypeIssues] # Argument to class must be a base class
def __init__(self, parent:Optional['QWidget'] = None, **kwargs:Dict[str,Any]) -> None:
super().__init__(parent, **kwargs)
Expand Down
1 change: 1 addition & 0 deletions src/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ disable='''
too-many-locals,
too-many-boolean-expressions,
too-many-nested-blocks,
too-many-positional-arguments,
cyclic-import,
duplicate-code,
'''
Expand Down
4 changes: 2 additions & 2 deletions src/requirements-dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ types-urllib3>=1.26.25.14
lxml-stubs>=0.5.1
mypy==1.11.2
pyright==1.1.381
ruff>=0.6.4
pylint==3.2.7
ruff>=0.6.7
pylint==3.3.0
pre-commit>=3.8.0
pytest>=8.3.3
pytest-cov==5.0.0
Expand Down
6 changes: 3 additions & 3 deletions src/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -42,19 +42,19 @@ pyusb==1.2.1
persist-queue==1.0.0
portalocker==2.10.1
xlrd==2.0.1
websockets==13.0.1
websockets==13.1
PyYAML==6.0.2
psutil==6.0.0
typing-extensions==4.10.0; python_version < '3.8' # required for supporting Final and TypeDict on Python <3.8
protobuf==5.28.1
protobuf==5.28.2
numpy==1.24.3; python_version < '3.9' # last Python 3.8 release
numpy==2.1.1; python_version >= '3.9'
scipy==1.10.1; python_version < '3.9' # last Python 3.8 release
scipy==1.14.1; python_version >= '3.9'
wquantiles==0.6
colorspacious==1.1.2
openpyxl==3.1.5
keyring==25.4.0
keyring==25.4.1
prettytable==3.11.0
lxml==5.3.0
matplotlib==3.7.3; python_version < '3.9' # last Python 3.8 release
Expand Down

0 comments on commit 8d7bf05

Please sign in to comment.