New options: - Save: save the log to a file (default to carla_log.txt) - Clear: clear the console log (also accessible via CTRL+L) - Auto-Scroll (default on): chooses wether it should scroll to keep up with new log entries or stay where it is Misc: - Small carla_host.ui cleanup (from Qt Designer) - Do not show the console scrollbars when there is nothing to scroll - Add some margin to the console to give it a more "console-like" feel Signed-off-by: Térence Clastres <t.clastres@gmail.com>tags/v2.2.0-RC1
@@ -7,7 +7,7 @@ | |||
<x>0</x> | |||
<y>0</y> | |||
<width>1045</width> | |||
<height>716</height> | |||
<height>741</height> | |||
</rect> | |||
</property> | |||
<property name="windowTitle"> | |||
@@ -67,7 +67,16 @@ | |||
<property name="spacing"> | |||
<number>0</number> | |||
</property> | |||
<property name="margin"> | |||
<property name="leftMargin"> | |||
<number>0</number> | |||
</property> | |||
<property name="topMargin"> | |||
<number>0</number> | |||
</property> | |||
<property name="rightMargin"> | |||
<number>0</number> | |||
</property> | |||
<property name="bottomMargin"> | |||
<number>0</number> | |||
</property> | |||
<item> | |||
@@ -179,21 +188,6 @@ | |||
<string>Logs</string> | |||
</attribute> | |||
<layout class="QHBoxLayout" name="horizontalLayout_4"> | |||
<property name="spacing"> | |||
<number>0</number> | |||
</property> | |||
<property name="leftMargin"> | |||
<number>0</number> | |||
</property> | |||
<property name="topMargin"> | |||
<number>0</number> | |||
</property> | |||
<property name="rightMargin"> | |||
<number>0</number> | |||
</property> | |||
<property name="bottomMargin"> | |||
<number>1</number> | |||
</property> | |||
<item> | |||
<widget class="QPlainTextEdit" name="text_logs"> | |||
<property name="font"> | |||
@@ -202,10 +196,10 @@ | |||
</font> | |||
</property> | |||
<property name="verticalScrollBarPolicy"> | |||
<enum>Qt::ScrollBarAlwaysOn</enum> | |||
<enum>Qt::ScrollBarAsNeeded</enum> | |||
</property> | |||
<property name="horizontalScrollBarPolicy"> | |||
<enum>Qt::ScrollBarAlwaysOn</enum> | |||
<enum>Qt::ScrollBarAsNeeded</enum> | |||
</property> | |||
<property name="lineWrapMode"> | |||
<enum>QPlainTextEdit::NoWrap</enum> | |||
@@ -218,6 +212,98 @@ | |||
</property> | |||
</widget> | |||
</item> | |||
<item alignment="Qt::AlignTop"> | |||
<widget class="QWidget" name="log_options" native="true"> | |||
<property name="enabled"> | |||
<bool>true</bool> | |||
</property> | |||
<property name="sizePolicy"> | |||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred"> | |||
<horstretch>0</horstretch> | |||
<verstretch>0</verstretch> | |||
</sizepolicy> | |||
</property> | |||
<property name="minimumSize"> | |||
<size> | |||
<width>0</width> | |||
<height>0</height> | |||
</size> | |||
</property> | |||
<layout class="QVBoxLayout" name="verticalLayout_8"> | |||
<property name="sizeConstraint"> | |||
<enum>QLayout::SetDefaultConstraint</enum> | |||
</property> | |||
<item> | |||
<widget class="QPushButton" name="logs_save"> | |||
<property name="cursor"> | |||
<cursorShape>ArrowCursor</cursorShape> | |||
</property> | |||
<property name="acceptDrops"> | |||
<bool>false</bool> | |||
</property> | |||
<property name="layoutDirection"> | |||
<enum>Qt::LeftToRight</enum> | |||
</property> | |||
<property name="autoFillBackground"> | |||
<bool>false</bool> | |||
</property> | |||
<property name="text"> | |||
<string> Save</string> | |||
</property> | |||
<property name="icon"> | |||
<iconset resource="../resources.qrc"> | |||
<normaloff>:/16x16/document-save.svgz</normaloff>:/16x16/document-save.svgz</iconset> | |||
</property> | |||
<property name="iconSize"> | |||
<size> | |||
<width>24</width> | |||
<height>24</height> | |||
</size> | |||
</property> | |||
<property name="autoDefault"> | |||
<bool>false</bool> | |||
</property> | |||
<property name="default"> | |||
<bool>false</bool> | |||
</property> | |||
<property name="flat"> | |||
<bool>false</bool> | |||
</property> | |||
</widget> | |||
</item> | |||
<item> | |||
<widget class="QPushButton" name="logs_clear"> | |||
<property name="text"> | |||
<string> Clear</string> | |||
</property> | |||
<property name="icon"> | |||
<iconset resource="../resources.qrc"> | |||
<normaloff>:/16x16/edit-clear.svgz</normaloff>:/16x16/edit-clear.svgz</iconset> | |||
</property> | |||
<property name="iconSize"> | |||
<size> | |||
<width>24</width> | |||
<height>24</height> | |||
</size> | |||
</property> | |||
<property name="shortcut"> | |||
<string>Ctrl+L</string> | |||
</property> | |||
</widget> | |||
</item> | |||
<item> | |||
<widget class="QCheckBox" name="logs_autoscroll"> | |||
<property name="text"> | |||
<string>Auto-Scroll</string> | |||
</property> | |||
<property name="checked"> | |||
<bool>true</bool> | |||
</property> | |||
</widget> | |||
</item> | |||
</layout> | |||
</widget> | |||
</item> | |||
</layout> | |||
</widget> | |||
</widget> | |||
@@ -336,7 +422,7 @@ | |||
<x>0</x> | |||
<y>0</y> | |||
<width>1045</width> | |||
<height>25</height> | |||
<height>42</height> | |||
</rect> | |||
</property> | |||
<widget class="QMenu" name="menu_File"> | |||
@@ -878,7 +964,7 @@ | |||
<property name="currentIndex"> | |||
<number>0</number> | |||
</property> | |||
<property name="tabBarAutoHide" stdset="0"> | |||
<property name="tabBarAutoHide"> | |||
<bool>false</bool> | |||
</property> | |||
<widget class="QWidget" name="tab_3"> | |||
@@ -205,6 +205,12 @@ class HostWindow(QMainWindow): | |||
self.fWithCanvas = withCanvas | |||
# ---------------------------------------------------------------------------------------------------- | |||
# Internal stuff (logs) | |||
self.autoscrollOnNewLog = True | |||
self.lastLogSliderPos = 0 | |||
# ---------------------------------------------------------------------------------------------------- | |||
# Set up GUI (engine stopped) | |||
@@ -387,6 +393,15 @@ class HostWindow(QMainWindow): | |||
self.ui.miniCanvasPreview.setRealParent(self) | |||
self.ui.tw_miniCanvas.tabBar().hide() | |||
# ---------------------------------------------------------------------------------------------------- | |||
# Set up GUI (logs) | |||
self.ui.text_logs.textChanged.connect(self.slot_logButtonsState) | |||
self.ui.logs_clear.clicked.connect(self.slot_logClear) | |||
self.ui.logs_save.clicked.connect(self.slot_logSave) | |||
self.ui.logs_autoscroll.stateChanged.connect(self.slot_toggleLogAutoscroll) | |||
self.ui.text_logs.verticalScrollBar().valueChanged.connect(self.slot_logSliderMoved) | |||
# ---------------------------------------------------------------------------------------------------- | |||
# Set up GUI (special stuff for Mac OS) | |||
@@ -540,6 +555,7 @@ class HostWindow(QMainWindow): | |||
# Final setup | |||
self.ui.text_logs.clear() | |||
self.slot_logButtonsState(False) | |||
self.setProperWindowTitle() | |||
# Disable non-supported features | |||
@@ -2189,6 +2205,48 @@ class HostWindow(QMainWindow): | |||
vsb.setValue(yp * vsb.maximum()) | |||
self.updateCanvasInitialPos() | |||
# -------------------------------------------------------------------------------------------------------- | |||
# Logs autoscroll, save and clear | |||
@pyqtSlot(Qt.CheckState) | |||
def slot_toggleLogAutoscroll(self, checked): | |||
self.autoscrollOnNewLog = bool(checked) | |||
if self.autoscrollOnNewLog: | |||
self.ui.text_logs.verticalScrollBar().setValue(self.ui.text_logs.verticalScrollBar().maximum()) | |||
@pyqtSlot(int) | |||
def slot_logSliderMoved(self, slider_pos): | |||
if self.ui.text_logs.verticalScrollBar().hasTracking() or self.autoscrollOnNewLog: | |||
self.lastLogSliderPos = slider_pos | |||
else: | |||
self.ui.text_logs.verticalScrollBar().setValue(self.lastLogSliderPos) | |||
@pyqtSlot() | |||
def slot_logButtonsState(self, enabled=True): | |||
self.ui.logs_clear.setEnabled(enabled) | |||
self.ui.logs_save.setEnabled(enabled) | |||
@pyqtSlot() | |||
def slot_logSave(self): | |||
filename, _ = QFileDialog.getSaveFileName(self, self.tr("Save Logs"),os.path.join( | |||
self.fSavedSettings[CARLA_KEY_MAIN_PROJECT_FOLDER], 'carla_log.txt')) | |||
if not filename: | |||
return | |||
try: | |||
with open(filename, "w") as logfile: | |||
logfile.write(self.ui.text_logs.toPlainText()) | |||
logfile.close() | |||
except: | |||
return | |||
@pyqtSlot() | |||
def slot_logClear(self): | |||
self.ui.text_logs.clear() | |||
self.ui.text_logs.appendPlainText("======= Logs cleared ========") | |||
self.slot_logButtonsState(False) | |||
# -------------------------------------------------------------------------------------------------------- | |||
# Timers | |||