Skip to content

Commit 3044fb3

Browse files
First Stylesheet and Invalid Cells Updating when changing layout (#67)
* Move coloring alongside row_deletion, column_deleton and copy/paste * Added some catches for adding values * added stylesheet * moved background color to stylesheet
1 parent a0a6b41 commit 3044fb3

6 files changed

Lines changed: 178 additions & 15 deletions

File tree

src/petab_gui/app.py

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
from pathlib import Path
1313

1414

15-
1615
def find_example(path: Path) -> Path:
1716
while path.parent != path:
1817
if (path / "example").is_dir():
@@ -26,11 +25,8 @@ class PEtabGuiApp(QApplication):
2625
def __init__(self):
2726
super().__init__(sys.argv)
2827

29-
# no need to instantiate a PEtab problem, as we are not using it
30-
#
31-
# petab_problem = petab.Problem.from_yaml(
32-
# find_example(Path(__file__).parent) / "problem.yaml"
33-
# )
28+
# Load the styleshee
29+
self.apply_stylesheet()
3430
self.model = PEtabModel()
3531
self.view = MainWindow()
3632
self.controller = MainController(self.view, self.model)
@@ -50,6 +46,17 @@ def event(self, event):
5046

5147
return super().event(event)
5248

49+
def apply_stylesheet(self):
50+
"""Load and apply the QSS stylesheet."""
51+
stylesheet_path = os.path.join(
52+
os.path.dirname(__file__), "stylesheet.css"
53+
)
54+
if os.path.exists(stylesheet_path):
55+
with open(stylesheet_path, "r") as f:
56+
self.setStyleSheet(f.read())
57+
else:
58+
print(f"Warning: Stylesheet '{stylesheet_path}' not found!")
59+
5360

5461
def main():
5562
app = PEtabGuiApp()

src/petab_gui/controllers/logger_controller.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,9 @@ def __init__(self, views):
1616
The view of the logger widget.
1717
"""
1818
self.views = views
19+
self.logger_level = 1
1920

20-
def log_message(self, message, color="black"):
21+
def log_message(self, message, color="black", loglevel=1):
2122
"""Log a message to the logger.
2223
2324
Parameters
@@ -27,6 +28,8 @@ def log_message(self, message, color="black"):
2728
color: str
2829
The color of the message. Default is black.
2930
"""
31+
if loglevel > self.logger_level:
32+
return
3033
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
3134
full_message = \
3235
f"[{timestamp}]\t <span style='color: {color};'>{message}</span>"

src/petab_gui/models/pandas_table_model.py

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,7 @@ def data(self, index, role=Qt.DisplayRole):
5252
return ""
5353
return str(value)
5454
elif role == Qt.BackgroundRole:
55-
if (row, column) in self._invalid_cells:
56-
return QColor(Qt.red)
57-
if (row, column) == (self._data_frame.shape[0], 0):
58-
return QColor(144, 238, 144, 150)
55+
return self.determine_background_color(row, column)
5956
return None
6057

6158
def flags(self, index):
@@ -395,6 +392,22 @@ def maybe_add_rows(self, start_row, n_rows):
395392
)
396393
self.layoutChanged.emit()
397394

395+
def determine_background_color(self, row, column):
396+
"""Determine the background color of a cell.
397+
398+
1. If it is the first column and last row, return light green.
399+
2. If it is an invalid cell, return red
400+
3. If it is an even row return light blue
401+
4. Otherwise return light green
402+
"""
403+
if (row, column) == (self._data_frame.shape[0], 0):
404+
return QColor(144, 238, 144, 150)
405+
if (row, column) in self._invalid_cells:
406+
return QColor(255, 100, 100, 150)
407+
if row % 2 == 0:
408+
return QColor(144, 190, 109, 102)
409+
return QColor(177, 217, 231, 102)
410+
398411

399412
class IndexedPandasTableModel(PandasTableModel):
400413
"""Table model for tables with named index."""
@@ -475,10 +488,7 @@ def data(self, index, role=Qt.DisplayRole):
475488
return ""
476489
return str(value)
477490
elif role == Qt.BackgroundRole:
478-
if (row, column) in self._invalid_cells:
479-
return QColor(Qt.red)
480-
if (row, column) == (self._data_frame.shape[0], 0):
481-
return QColor(144, 238, 144, 150)
491+
return self.determine_background_color(row, column)
482492
return None
483493

484494
def headerData(self, section, orientation, role=Qt.DisplayRole):

src/petab_gui/stylesheet.css

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
/* 🌟 Light Mode */
2+
QWidget {
3+
background-color: #f8f9fa; /* Soft background */
4+
color: #333; /* Dark text */
5+
font-family: "Arial", sans-serif;
6+
}
7+
8+
/* Dark Mode */
9+
QWidget[darkMode="true"] {
10+
background-color: #2b2b2b;
11+
color: #f8f9fa;
12+
}
13+
14+
/* 🌟 Ensure alternate row colors but allow BackgroundRole */
15+
QTableView {
16+
background: transparent; /* Keep the overall table background transparent */
17+
border: none;
18+
border-radius: 10px;
19+
padding: 5px;
20+
gridline-color: transparent;
21+
}
22+
23+
/* 🎨 Restore table header style */
24+
QHeaderView::section {
25+
background-color: #d5dcef;
26+
font-weight: bold;
27+
border: none;
28+
padding: 6px;
29+
border-radius: 5px;
30+
}
31+
32+
/* 🚀 Selection should remain visible */
33+
QTableView::item:selected {
34+
background-color: rgba(122, 93, 204, 0.2);
35+
color: white;
36+
border: none;
37+
}
38+
39+
/* Fix cell editing */
40+
QTableView::item:selected:active {
41+
background-color: rgba(122, 93, 204, 0.6);
42+
color: white;
43+
border: none;
44+
outline: none;
45+
}
46+
47+
QTableView QLineEdit {
48+
background-color: white;
49+
color: black;
50+
padding: 3px;
51+
border: 2px solid #7A5DCC;
52+
border-radius: 5px;
53+
}
54+
55+
56+
QMenuBar {
57+
background-color: #dee2e6; /* Soft gray */
58+
padding: 6px;
59+
}
60+
61+
QMenuBar::item {
62+
background-color: transparent;
63+
padding: 8px 16px;
64+
border-radius: 5px;
65+
}
66+
67+
/* Hover Effect */
68+
QMenuBar::item:selected {
69+
background-color: #7A5DCC; /* Purple */
70+
color: white;
71+
}
72+
73+
/* Menu Items */
74+
QMenu {
75+
background-color: white;
76+
border: 1px solid #ccc;
77+
}
78+
79+
QMenu::item {
80+
padding: 8px 12px;
81+
}
82+
83+
QMenu::item:selected {
84+
background-color: #7A5DCC; /* Purple hover */
85+
color: white;
86+
}
87+
/* Rounded Buttons */
88+
QPushButton {
89+
background-color: #d5e8d4; /* Light green */
90+
color: black;
91+
border-radius: 15px;
92+
padding: 8px 16px;
93+
border: 2px solid transparent;
94+
}
95+
96+
/* Button Hover */
97+
QPushButton:hover {
98+
background-color: #b7e1b5; /* Slightly darker green */
99+
}
100+
101+
/* Input Fields */
102+
QLineEdit, QTextEdit {
103+
background-color: white;
104+
border: 2px solid #ccc;
105+
border-radius: 10px;
106+
padding: 6px;
107+
}
108+
109+
/* Selected Input */
110+
QLineEdit:focus, QTextEdit:focus {
111+
border: 2px solid #7A5DCC; /* Purple border when focused */
112+
}
113+
114+
/* 🌟 Rounded Dock Widgets */
115+
QDockWidget {
116+
background-color: #eef1f6; /* Light grayish-blue */
117+
border-radius: 10px;
118+
border: 1px solid #ccc;
119+
}
120+
121+
/* 🌟 Dock Title Styling */
122+
QDockWidget::title {
123+
background-color: #d5dcef; /* Soft blue */
124+
padding: 5px;
125+
border-top-left-radius: 10px;
126+
border-top-right-radius: 10px;
127+
font-weight: bold;
128+
}
129+
130+
/* 🌟 Hover effect for close button */
131+
QDockWidget::close-button {
132+
border: none;
133+
background: transparent;
134+
}
135+
136+
/* Change close button color on hover */
137+
QDockWidget::close-button:hover {
138+
background-color: #ffcccc; /* Light red */
139+
border-radius: 5px;
140+
}
141+

src/petab_gui/views/main_view.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ def __init__(self):
116116

117117
# drag drop
118118
self.setAcceptDrops(True)
119+
# self.dumpObjectTree()
119120

120121

121122
def dragEnterEvent(self, event):

src/petab_gui/views/table_view.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ def __init__(self, title, parent=None):
2424
layout.addWidget(self.table_view)
2525
# Dictionary to store column-specific completers
2626
self.completers = {}
27+
self.table_view.setAlternatingRowColors(True)
2728

2829
def copy_to_clipboard(self):
2930
selected_rect, rect_start = get_selected_rectangles(

0 commit comments

Comments
 (0)