Skip to content

Commit e47429f

Browse files
committed
The OutputConsole now use the same stylesheet used by preditor
Updating the style of the controller will automatically apply that style to the OutputWindow. This is not enabled by default for ConsoleBase or ConsolePrEdit.
1 parent cb28fd9 commit e47429f

File tree

4 files changed

+134
-17
lines changed

4 files changed

+134
-17
lines changed

examples/output_console.py

Lines changed: 41 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
import logging
88
import sys
9+
from argparse import ArgumentParser
910

1011
import Qt
1112
from Qt.QtCore import QDateTime
@@ -26,7 +27,7 @@
2627

2728

2829
class ExampleApp(QMainWindow):
29-
def __init__(self, parent=None):
30+
def __init__(self, parent=None, init_preditor=True):
3031
super().__init__(parent=parent)
3132
# Use a .ui file to simplify the example code setup.
3233
Qt.QtCompat.loadUi(__file__.replace(".py", ".ui"), self)
@@ -40,6 +41,8 @@ def __init__(self, parent=None):
4041
self.uiAllLoggingChangeHandlersBTN.released.connect(
4142
self.all_logging_change_handlers
4243
)
44+
self.uiUsePrEditorStyleCHK.toggled.connect(self.set_stdout_style)
45+
self.uiRemovePrEditorStyleBTN.released.connect(self.clear_stdout_style)
4346
self.uiLoggingCriticalBTN.released.connect(self.level_critical)
4447
self.uiLoggingErrorBTN.released.connect(self.level_error)
4548
self.uiLoggingWarningBTN.released.connect(self.level_warning)
@@ -51,12 +54,15 @@ def __init__(self, parent=None):
5154
self.uiSendLoggingBTN.released.connect(self.send_logging)
5255

5356
# 1. Create the preditor instance and connect to the console's controllers
54-
plog = preditor.instance(parent=self, create=True)
55-
preditor.connect_preditor(self)
56-
self.uiAllLog.controller = plog
57-
self.uiSelectLog.controller = plog
58-
self.uiStdout.controller = plog
59-
self.uiStderr.controller = plog
57+
if init_preditor:
58+
plog = preditor.instance(parent=self, create=True)
59+
preditor.connect_preditor(self)
60+
self.uiAllLog.controller = plog
61+
self.uiSelectLog.controller = plog
62+
self.uiStdout.controller = plog
63+
self.uiStderr.controller = plog
64+
else:
65+
self.setWindowTitle(f"{self.windowTitle()} - No PrEditor")
6066

6167
# 2. Configure the various OutputConsole widgets.
6268
# Note: this can be done in the .ui file, but for this example we will
@@ -149,6 +155,11 @@ def clear_all(self):
149155
self.uiStdout.clear()
150156
self.uiStderr.clear()
151157

158+
def clear_stdout_style(self):
159+
"""Reset uiStdout's style to not use PrEditor's style."""
160+
self.uiUsePrEditorStyleCHK.setChecked(False)
161+
self.uiStdout.setStyleSheet(None)
162+
152163
def level_critical(self):
153164
logging.root.setLevel(logging.CRITICAL)
154165

@@ -176,6 +187,14 @@ def print_time_stderr(self):
176187
def raise_exception(self):
177188
raise RuntimeError(self.message_time())
178189

190+
def set_stdout_style(self, state):
191+
"""Enable/disable uiStdout using PrEditor's style.
192+
193+
Note: Disabling it doesn't clear the style, just prevent it from being
194+
automatically updated when changed in PrEditor.
195+
"""
196+
self.uiStdout.use_console_stylesheet = state
197+
179198
def send_logging(self):
180199
logger_a.critical("A critical msg for logger_a")
181200
logger_a.error("A error msg for logger_a")
@@ -198,18 +217,27 @@ def send_logging(self):
198217

199218

200219
if __name__ == '__main__':
220+
parser = ArgumentParser("Example of using OutputConsole features.")
221+
parser.add_argument(
222+
"--no-preditor",
223+
action="store_true",
224+
help="Don't init and install the PrEditor console.",
225+
)
226+
args = parser.parse_args()
227+
201228
# Configure PrEditor for this application, start capturing all text output
202229
# from stderr/stdout so once PrEditor is launched, it can show this text.
203230
# This does not initialize any QtGui/QtWidgets.
204-
preditor.configure(
205-
# This is the name used to store PrEditor preferences and workboxes
206-
# specific to this application.
207-
'output_console',
208-
)
231+
if not args.no_preditor:
232+
preditor.configure(
233+
# This is the name used to store PrEditor preferences and workboxes
234+
# specific to this application.
235+
'output_console',
236+
)
209237

210238
# Create a Gui Application allowing the user to show PrEditor
211239
app = QApplication(sys.argv)
212-
main_gui = ExampleApp()
240+
main_gui = ExampleApp(init_preditor=not args.no_preditor)
213241

214242
main_gui.show()
215243
app.exec_()

examples/output_console.ui

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,11 @@
2626
</property>
2727
<layout class="QHBoxLayout" name="horizontalLayout_3">
2828
<item>
29-
<widget class="OutputConsole" name="uiAllLog"/>
29+
<widget class="OutputConsole" name="uiAllLog">
30+
<property name="use_console_stylesheet" stdset="0">
31+
<bool>true</bool>
32+
</property>
33+
</widget>
3034
</item>
3135
<item>
3236
<layout class="QGridLayout" name="gridLayout">
@@ -126,9 +130,46 @@
126130
<property name="title">
127131
<string>Stdout</string>
128132
</property>
129-
<layout class="QVBoxLayout" name="verticalLayout_2">
130-
<item>
131-
<widget class="OutputConsole" name="uiStdout"/>
133+
<layout class="QGridLayout" name="gridLayout_2">
134+
<item row="1" column="1">
135+
<widget class="QPushButton" name="uiRemovePrEditorStyleBTN">
136+
<property name="toolTip">
137+
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Reset stylesheet to empty and disable Use PrEditor Style Sheet.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
138+
</property>
139+
<property name="text">
140+
<string>Remove Style Sheet</string>
141+
</property>
142+
</widget>
143+
</item>
144+
<item row="1" column="0">
145+
<widget class="QCheckBox" name="uiUsePrEditorStyleCHK">
146+
<property name="toolTip">
147+
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Enable using the stylesheet from the PrEditor instances Options -&amp;gt; Style menu. This OutputConsole doesn't have it enabled by default so it doesn't have the stylesheet applied. Checking this will load the style sheet. If you then uncheck it, the style sheet won't be cleared but it will no longer respect the PrEditor Options -&amp;gt; Style changes.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
148+
</property>
149+
<property name="text">
150+
<string>Use PrEditor Style Sheet</string>
151+
</property>
152+
</widget>
153+
</item>
154+
<item row="1" column="2">
155+
<spacer name="horizontalSpacer">
156+
<property name="orientation">
157+
<enum>Qt::Horizontal</enum>
158+
</property>
159+
<property name="sizeHint" stdset="0">
160+
<size>
161+
<width>40</width>
162+
<height>20</height>
163+
</size>
164+
</property>
165+
</spacer>
166+
</item>
167+
<item row="0" column="0" colspan="3">
168+
<widget class="OutputConsole" name="uiStdout">
169+
<property name="use_console_stylesheet" stdset="0">
170+
<bool>false</bool>
171+
</property>
172+
</widget>
132173
</item>
133174
</layout>
134175
</widget>

preditor/gui/console_base.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,10 @@ class ConsoleBase(QTextEdit):
3939

4040
def __init__(self, parent: QWidget, controller: Optional[LoggerWindow] = None):
4141
super().__init__(parent)
42+
self._controller = None
43+
self._stylesheet_changed_meta = None
4244
self.controller = controller
45+
4346
self._first_show = True
4447
# The last time a repaint call was made when writing. Used to limit the
4548
# number of refreshes to once per X.X seconds.
@@ -156,7 +159,14 @@ def controller(self) -> Optional[LoggerWindow]:
156159

157160
@controller.setter
158161
def controller(self, value: LoggerWindow):
162+
if self._stylesheet_changed_meta and self.controller:
163+
# Remove the existing signals if connected
164+
self.controller.styleSheetChanged.disconnect(self._stylesheet_changed_meta)
165+
self._stylesheet_changed_meta = None
166+
159167
self._controller = value
168+
# Ensure the stylesheet is up to date and stays up to date.
169+
self.init_stylesheet()
160170

161171
def codeHighlighter(self):
162172
"""Get the code highlighter for the console
@@ -343,6 +353,22 @@ def init_excepthook(self, attrName=None, value=None):
343353
if self.write_error in PreditorExceptHook.callbacks:
344354
PreditorExceptHook.callbacks.remove(self.write_error)
345355

356+
def init_stylesheet(self, attrName=None, value=None):
357+
if not self.controller:
358+
return
359+
360+
signal = self.controller.styleSheetChanged
361+
if self.use_console_stylesheet:
362+
# Apply the stylesheet and ensure that future updates are respected
363+
self._stylesheet_changed_meta = signal.connect(self.update_stylesheet)
364+
self.update_stylesheet()
365+
366+
elif self._stylesheet_changed_meta:
367+
# if disabling use_console_stylesheet, then remove the existing
368+
# connection if it was previously connected.
369+
signal.disconnect(self._stylesheet_changed_meta)
370+
self._stylesheet_changed_meta = None
371+
346372
def maybeRepaint(self, force=False):
347373
"""Forces the console to repaint if enough time has elapsed from the
348374
last repaint.
@@ -579,6 +605,12 @@ def update_streams(self, attrName=None, value=None):
579605
else:
580606
self.stream_manager.remove_callback(self.write)
581607

608+
def update_stylesheet(self):
609+
sheet = None
610+
if self.controller:
611+
sheet = self.controller.styleSheet()
612+
self.setStyleSheet(sheet)
613+
582614
def get_logging_info(self, name):
583615
# Look for a specific rule to handle this logging message
584616
parts = name.split(".")
@@ -864,6 +896,16 @@ def logging_formatter_str(self, value):
864896
stream_echo_stderr is disabled or you likely will get duplicate output.
865897
"""
866898

899+
use_console_stylesheet = QtPropertyInit(
900+
"_use_console_stylesheet", False, callback=init_stylesheet
901+
)
902+
"""Set this widgets stylesheet to the PrEditor instance's style sheet.
903+
904+
This ensures that the style of random OutputConsoles match even when not
905+
parented to PrEditor. Enabling this will update the widgets style sheet, but
906+
disabling it will not update the style sheet.
907+
"""
908+
867909

868910
# Build and add the class properties for regex patterns so subclasses can use them.
869911
ConsoleBase._ConsoleBase__defineRegexPatterns()

preditor/gui/output_console.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
1+
from ..utils.cute import QtPropertyInit
12
from .console_base import ConsoleBase
23

34

45
class OutputConsole(ConsoleBase):
56
"""A text widget used to show stdout/stderr writes."""
7+
8+
# Enable these settings by default
9+
use_console_stylesheet = QtPropertyInit(
10+
"_use_console_stylesheet", True, callback=ConsoleBase.init_stylesheet
11+
)

0 commit comments

Comments
 (0)