Gui cleanups, part I.

This commit is contained in:
2026-01-06 10:53:15 +01:00
parent 731566e7d1
commit 5c52b1e936
10 changed files with 139 additions and 174 deletions

View File

@@ -52,8 +52,6 @@ BCMainWindow::BCMainWindow(QWidget *parent)
setupUi(this); setupUi(this);
// den pimp-my-ride-button schalten wir vorerst aus.
_pimpButton->hide();
// Wir schreiben den 'initMainWindow()' Aufruf mit Hilfe des // Wir schreiben den 'initMainWindow()' Aufruf mit Hilfe des
// timers in die Event-Queue, damit er erst ausgeführt wird, // timers in die Event-Queue, damit er erst ausgeführt wird,
@@ -111,14 +109,11 @@ void BCMainWindow::initMainWindow()
_devicePanels[BCDevice::ID::Console] = _consolePanel; _devicePanels[BCDevice::ID::Console] = _consolePanel;
_devicePanels[BCDevice::ID::Battery] = _batteryPanel; _devicePanels[BCDevice::ID::Battery] = _batteryPanel;
_devicePanels[BCDevice::ID::Motor] = _motorPanel; _devicePanels[BCDevice::ID::Motor] = _motorPanel;
//_devicePanels[BCDevice::ID::Pimp] = _pimpPanel;
// Die actions an die Buttons binden // Die actions an die Buttons binden
configureAction(_motorButton, _motorAction, BCDevice::ID::Motor ); configureAction(_motorButton, _motorAction, BCDevice::ID::Motor );
configureAction(_consoleButton, _consoleAction, BCDevice::ID::Console ); configureAction(_consoleButton, _consoleAction, BCDevice::ID::Console );
configureAction(_batteryButton, _batteryAction, BCDevice::ID::Battery ); configureAction(_batteryButton, _batteryAction, BCDevice::ID::Battery );
//configureAction(_pimpButton, _pimpAction, BCDevice::ID::Pimp );
/* /*
bool m_isDarkMode = false; bool m_isDarkMode = false;
@@ -151,7 +146,7 @@ void BCMainWindow::initMainWindow()
connect( _syncButton, &QToolButton::clicked, this, &BCMainWindow::onSyncDeviceView ); connect( _syncButton, &QToolButton::clicked, this, &BCMainWindow::onSyncDeviceView );
connect( &_transmitter, &BCTransmitter::valueUpdated, this, &BCMainWindow::onValueUpdated ); connect( &_transmitter, &BCTransmitter::valueUpdated, this, &BCMainWindow::onValueUpdated );
connect(this, &BCMainWindow::requestValueUpdate, &_transmitter, &BCTransmitter::onEnqueueValue); connect(this, &BCMainWindow::requestValueUpdate, &_transmitter, &BCTransmitter::onUpdateValue);
connect(&_worker, &QThread::finished, &_transmitter, &QObject::deleteLater); connect(&_worker, &QThread::finished, &_transmitter, &QObject::deleteLater);
connect( &_transmitter, &BCTransmitter::driverStateChanged, this, &BCMainWindow::onDriverStateChanged ); connect( &_transmitter, &BCTransmitter::driverStateChanged, this, &BCMainWindow::onDriverStateChanged );
@@ -322,7 +317,7 @@ void BCMainWindow::onSyncDeviceView()
// wir setzen auf 'lesen' // wir setzen auf 'lesen'
value->state.setFlag( BCValue::State::ReadMe ); value->state.setFlag( BCValue::State::ReadMe );
// statt '_transmitter.onEnqueueValue( value )' müssen wir hier // statt '_transmitter.onUpdateValue( value )' müssen wir hier
// über emit requestValueUpdate() zur Thread sysnchronisation // über emit requestValueUpdate() zur Thread sysnchronisation
// entkoppeln, // entkoppeln,

View File

@@ -120,28 +120,6 @@
</property> </property>
</widget> </widget>
</item> </item>
<item alignment="Qt::AlignmentFlag::AlignHCenter">
<widget class="QToolButton" name="_pimpButton">
<property name="minimumSize">
<size>
<width>64</width>
<height>64</height>
</size>
</property>
<property name="text">
<string>...</string>
</property>
<property name="iconSize">
<size>
<width>48</width>
<height>48</height>
</size>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
<item> <item>
<spacer name="verticalSpacer"> <spacer name="verticalSpacer">
<property name="orientation"> <property name="orientation">
@@ -157,21 +135,73 @@
</item> </item>
<item alignment="Qt::AlignmentFlag::AlignHCenter"> <item alignment="Qt::AlignmentFlag::AlignHCenter">
<widget class="QToolButton" name="_syncButton"> <widget class="QToolButton" name="_syncButton">
<property name="text"> <property name="minimumSize">
<string>Sync</string> <size>
<width>64</width>
<height>64</height>
</size>
</property> </property>
</widget>
</item>
<item>
<widget class="QToolButton" name="_connectButton">
<property name="text"> <property name="text">
<string>Connect</string> <string>SYNC</string>
</property> </property>
<property name="checkable"> <property name="iconSize">
<size>
<width>48</width>
<height>48</height>
</size>
</property>
<property name="autoRaise">
<bool>true</bool> <bool>true</bool>
</property> </property>
</widget> </widget>
</item> </item>
<item alignment="Qt::AlignmentFlag::AlignHCenter">
<widget class="QToolButton" name="_connectButton">
<property name="minimumSize">
<size>
<width>64</width>
<height>64</height>
</size>
</property>
<property name="text">
<string>CONNECT</string>
</property>
<property name="iconSize">
<size>
<width>48</width>
<height>48</height>
</size>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
<item alignment="Qt::AlignmentFlag::AlignHCenter">
<widget class="QToolButton" name="_exitButton">
<property name="minimumSize">
<size>
<width>64</width>
<height>64</height>
</size>
</property>
<property name="text">
<string>Quit</string>
</property>
<property name="iconSize">
<size>
<width>48</width>
<height>48</height>
</size>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
</layout> </layout>
</widget> </widget>
</item> </item>
@@ -190,7 +220,7 @@
<number>0</number> <number>0</number>
</property> </property>
<property name="currentIndex"> <property name="currentIndex">
<number>3</number> <number>0</number>
</property> </property>
<widget class="BCDeviceView" name="_consolePanel"> <widget class="BCDeviceView" name="_consolePanel">
<property name="frameShape"> <property name="frameShape">
@@ -279,35 +309,6 @@
<bool>false</bool> <bool>false</bool>
</attribute> </attribute>
</widget> </widget>
<widget class="BCDeviceView" name="_pimpPanel">
<property name="frameShape">
<enum>QFrame::Shape::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Shadow::Plain</enum>
</property>
<property name="lineWidth">
<number>0</number>
</property>
<property name="showGrid">
<bool>false</bool>
</property>
<property name="gridStyle">
<enum>Qt::PenStyle::NoPen</enum>
</property>
<property name="BCHeaderLabel" stdset="0">
<string>Pimp my Ride ...</string>
</property>
<attribute name="horizontalHeaderVisible">
<bool>false</bool>
</attribute>
<attribute name="horizontalHeaderStretchLastSection">
<bool>true</bool>
</attribute>
<attribute name="verticalHeaderVisible">
<bool>false</bool>
</attribute>
</widget>
</widget> </widget>
</item> </item>
</layout> </layout>
@@ -319,21 +320,6 @@
<string notr="true">background-color: #DADADA</string> <string notr="true">background-color: #DADADA</string>
</property> </property>
</widget> </widget>
<action name="_pimpAction">
<property name="checkable">
<bool>true</bool>
</property>
<property name="icon">
<iconset>
<normaloff>:restart.png</normaloff>:restart.png</iconset>
</property>
<property name="text">
<string>pimp</string>
</property>
<property name="toolTip">
<string>Pimp my Ride</string>
</property>
</action>
<action name="_motorAction"> <action name="_motorAction">
<property name="icon"> <property name="icon">
<iconset> <iconset>
@@ -373,7 +359,7 @@
<action name="_exitAction"> <action name="_exitAction">
<property name="icon"> <property name="icon">
<iconset> <iconset>
<normaloff>:exit.png</normaloff>:exit.png</iconset> <normaloff>:exit.svg</normaloff>:exit.svg</iconset>
</property> </property>
<property name="text"> <property name="text">
<string>Exit</string> <string>Exit</string>

View File

@@ -32,6 +32,7 @@
#include <QThread> #include <QThread>
#include <QDebug> #include <QDebug>
#include <QCoreApplication>
#include <bctransmitter.h> #include <bctransmitter.h>
@@ -40,7 +41,7 @@
*/ */
BCTransmitter::BCTransmitter(QObject *parent) BCTransmitter::BCTransmitter(QObject *parent)
: QObject(parent), _isBusy(false) : QObject(parent)//, _isBusy(false)
{ {
//_canDriver = new BCDriverTinyCan{this}; //_canDriver = new BCDriverTinyCan{this};
_canDriver = &_dummyDriver; _canDriver = &_dummyDriver;
@@ -56,18 +57,24 @@ BCTransmitter::BCTransmitter(QObject *parent)
void BCTransmitter::onToggleDriverConnection( bool connect ) void BCTransmitter::onToggleDriverConnection( bool connect )
{ {
qDebug() << " --- onToggleDriverConnection: " << connect; qDebug() << " --- onToggleDriverConnection: " << connect;
emit driverStateChanged(BCDriver::DriverState::Initialized, "BUSY!");
bc::delay_millis(350);
// kill all pending stuff
QCoreApplication::removePostedEvents(this, QEvent::MetaCall);
// FIX! Ende der current op abwarten! // FIX! Ende der current op abwarten!
BCDriver::DriverState state = connect ? BCDriver::DriverState::DeviceReady : BCDriver::DriverState::NotPresent; BCDriver::DriverState state = connect ? BCDriver::DriverState::DeviceReady : BCDriver::DriverState::NotPresent;
const QString& message = connect ? "Trying to connect" : " FAILED"; const QString& message = connect ? "Trying to connect" : " FAILED";
emit driverStateChanged(state, message); emit driverStateChanged(state, message);
return; return;
/*
// Hier sind wir noch in GUI Thread // Hier sind wir noch in GUI Thread
QMutexLocker locker(&_mutex); QMutexLocker locker(&_mutex);
// weitere operation stoppen // weitere operation stoppen
_isBusy = true; _isBusy = true;
connect ? connectCanDriver() : disconnectCanDriver(); connect ? connectCanDriver() : disconnectCanDriver();
_isBusy = false; _isBusy = false;
*/
} }
@@ -120,50 +127,18 @@ void BCTransmitter::disconnectCanDriver()
} }
void BCTransmitter::onEnqueueValue( BCValuePtrConst value) void BCTransmitter::onUpdateValue( BCValuePtrConst valuePtr)
{ {
// wir stellen hier auf die arte Tour sicher, das onEnqueueValue // wir stellen hier auf die harte Tour sicher, das onUpdateValue
// nicht aus dem Parent-Thread direkt sondern über die EventQueue aufgerufen wurde. // nicht aus dem Parent-Thread direkt sondern über die EventQueue aufgerufen wurde.
Q_ASSERT(QThread::currentThread() == this->thread()); Q_ASSERT(QThread::currentThread() == this->thread());
// Hier sind wir noch in GUI Thread // Wir arbeiten hier ohne besondere Threadsynchronisation, mutexed o.ä: Die
//QMutexLocker locker(&_mutex); // entkoppelung und serialisierung passiert bereits durch die Qt-Eventqueue.
_valueQueue.enqueue( value ); // Das klappt aber nur in der hier gewählten Konstellation mit einer Parent-Thread
// und einem Worker.
// wir wollen nicht den ganzen Value verschicken, erstrecht
// wollen wir nicht den Value in verschiedenen Threads gleichzeitig
// in die Hand nehmen, also hantieren wir nur mit den Inidizes.
// Trigger processing im Event-Loop des Worker Threads
// invokeMethod mit QueuedConnection entkoppelt den Aufruf,
// damit onEnqueueValue sofort zurückkehrt (non-blocking für den Aufrufer).
//QMetaObject::invokeMethod(this, "onProcessValue", Qt::QueuedConnection);
onProcessValue();
}
void BCTransmitter::onProcessValue()
{
//if (_isBusy)
// return;
_isBusy = true;
while (true)
{
BCValuePtrConst valuePtr{};
{
//QMutexLocker locker(&_mutex);
if (_valueQueue.isEmpty())
{
_isBusy = false;
break; // Schleife verlassen, warten auf neue Events
}
valuePtr =_valueQueue.dequeue();
} // Mutex wird hier freigegeben! WICHTIG: Execute ohne Lock!
// Kosmetik // Kosmetik
const BCValue& value = *(valuePtr.get()); const BCValue& value = *(valuePtr.get());
@@ -209,9 +184,11 @@ void BCTransmitter::onProcessValue()
//bc::processEventsFor(150); //bc::processEventsFor(150);
bc::delay_millis(150); bc::delay_millis(150);
}
} }
void BCTransmitter::onProcessValue()
{}
TransmitResult BCTransmitter::readByteValue( uint32_t deviceID, uint8_t registerID ) TransmitResult BCTransmitter::readByteValue( uint32_t deviceID, uint8_t registerID )
{ {

View File

@@ -63,7 +63,7 @@ public:
public slots: public slots:
void onToggleDriverConnection( bool connect ); void onToggleDriverConnection( bool connect );
void onEnqueueValue(BCValuePtrConst value ); void onUpdateValue(BCValuePtrConst valuePtr );
void onProcessValue(); void onProcessValue();
void onStartNativeDriver(); void onStartNativeDriver();
@@ -80,11 +80,11 @@ private:
TransmitResult readByteValue( uint32_t deviceID, uint8_t registerID ); TransmitResult readByteValue( uint32_t deviceID, uint8_t registerID );
TransmitResult readWordValue( uint32_t deviceID, uint8_t registerID ); TransmitResult readWordValue( uint32_t deviceID, uint8_t registerID );
using BCDataQueue = QQueue<BCValuePtrConst>; //using BCDataQueue = QQueue<BCValuePtrConst>;
BCDataQueue _valueQueue; //BCDataQueue _valueQueue;
QMutex _mutex; //QMutex _mutex;
std::atomic<bool> _isBusy{ false }; //std::atomic<bool> _isBusy{ false };
// __fix! // __fix!
BCDriver* _canDriver{}; BCDriver* _canDriver{};

View File

@@ -11,11 +11,13 @@
<file alias="important.png">resources/important.png</file> <file alias="important.png">resources/important.png</file>
<file alias="restart.png">resources/restart.png</file> <file alias="restart.png">resources/restart.png</file>
<file alias="splash.png">resources/splash.png</file> <file alias="splash.png">resources/splash.png</file>
<file alias="connect.png">resources/connect.png</file> <file alias="xconnect.png">resources/connect.png</file>
<file alias="connected.png">resources/connected.png</file> <file alias="connected.png">resources/connected.png</file>
<file alias="disconnected.png">resources/disconnected.png</file> <file alias="disconnected.png">resources/disconnected.png</file>
<file>resources/connect_white.svg</file> <file>resources/connect_white.svg</file>
<file>resources/sync_green.svg</file> <file alias="connect">resources/a_connect.svg</file>
<file>resources/sync_yellow.svg</file> <file alias="exit.svg">resources/a_exit.svg</file>
<file alias="sync_green">resources/a_sync_green.svg</file>
<file alias="sync_yellow">resources/a_sync_yellow.svg</file>
</qresource> </qresource>
</RCC> </RCC>

1
resources/a_connect.svg Normal file
View File

@@ -0,0 +1 @@
<svg width="24" height="24" fill="none" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M8.25 4a.75.75 0 0 1 .743.648L9 4.75v2.773l1.874 2.815a.75.75 0 0 1 .117.306l.009.11v4.496a.75.75 0 0 1-.649.743L10.25 16H8.996v3.254a.75.75 0 0 1-1.492.101l-.007-.101L7.496 16 5.5 15.999v3.258a.75.75 0 0 1-1.493.101l-.006-.101L4 15.999 2.75 16a.75.75 0 0 1-.742-.648l-.007-.102v-4.496a.75.75 0 0 1 .071-.32l.055-.096 1.874-2.815V4.75a.75.75 0 0 1 1.493-.102l.007.102v3a.75.75 0 0 1-.072.32l-.054.096-1.874 2.815V14.5H9.5v-3.52L7.625 8.167a.75.75 0 0 1-.117-.306L7.5 7.75v-3A.75.75 0 0 1 8.25 4Zm7.004.001h4.496a.75.75 0 0 1 .743.649l.007.101L20.499 8h.75a.75.75 0 0 1 .744.648L22 8.75v4.496c0 .111-.025.22-.072.32l-.054.096L20 16.477v2.773a.75.75 0 0 1-1.494.102l-.006-.102v-3c0-.11.024-.22.071-.32l.054-.096L20.5 13.02V9.5h-5.998v3.52l1.874 2.814a.749.749 0 0 1 .118.306l.008.11v3a.75.75 0 0 1-1.493.102l-.007-.102v-2.773l-1.874-2.815a.75.75 0 0 1-.118-.306l-.008-.11V8.75a.75.75 0 0 1 .648-.743L13.752 8h.752V4.751a.75.75 0 0 1 .649-.743l.101-.007h4.496-4.496ZM19 5.501h-2.996V8h2.995V5.501Z" fill="#000000"/></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

1
resources/a_exit.svg Normal file
View File

@@ -0,0 +1 @@
<svg width="24" height="24" fill="none" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M12 2c5.523 0 10 4.477 10 10s-4.477 10-10 10S2 17.523 2 12 6.477 2 12 2Zm0 1.5a8.5 8.5 0 1 0 0 17 8.5 8.5 0 0 0 0-17Zm3.446 4.897.084.073a.75.75 0 0 1 .073.976l-.073.084L13.061 12l2.47 2.47a.75.75 0 0 1 .072.976l-.073.084a.75.75 0 0 1-.976.073l-.084-.073L12 13.061l-2.47 2.47a.75.75 0 0 1-.976.072l-.084-.073a.75.75 0 0 1-.073-.976l.073-.084L10.939 12l-2.47-2.47a.75.75 0 0 1-.072-.976l.073-.084a.75.75 0 0 1 .976-.073l.084.073L12 10.939l2.47-2.47a.75.75 0 0 1 .976-.072Z" fill="#000000"/></svg>

After

Width:  |  Height:  |  Size: 599 B

View File

@@ -0,0 +1 @@
<svg width="48" height="48" fill="none" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M16 8.25a.75.75 0 0 1 1.5 0v3.25a.75.75 0 0 1-.75.75H14a.75.75 0 0 1 0-1.5h1.27A3.502 3.502 0 0 0 12 8.5c-1.093 0-2.037.464-2.673 1.23a.75.75 0 1 1-1.154-.96C9.096 7.66 10.463 7 12 7c1.636 0 3.088.785 4 2v-.75ZM8 15v.75a.75.75 0 0 1-1.5 0v-3a.75.75 0 0 1 .75-.75H10a.75.75 0 0 1 0 1.5H8.837a3.513 3.513 0 0 0 5.842.765.75.75 0 1 1 1.142.972A5.013 5.013 0 0 1 8 15Zm4-13C6.477 2 2 6.477 2 12s4.477 10 10 10 10-4.477 10-10S17.523 2 12 2Zm8.5 10a8.5 8.5 0 1 1-17 0 8.5 8.5 0 0 1 17 0Z" fill="#00FF00"/></svg>

After

Width:  |  Height:  |  Size: 609 B

View File

@@ -0,0 +1 @@
<svg width="48" height="48" fill="none" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M16 8.25a.75.75 0 0 1 1.5 0v3.25a.75.75 0 0 1-.75.75H14a.75.75 0 0 1 0-1.5h1.27A3.502 3.502 0 0 0 12 8.5c-1.093 0-2.037.464-2.673 1.23a.75.75 0 1 1-1.154-.96C9.096 7.66 10.463 7 12 7c1.636 0 3.088.785 4 2v-.75ZM8 15v.75a.75.75 0 0 1-1.5 0v-3a.75.75 0 0 1 .75-.75H10a.75.75 0 0 1 0 1.5H8.837a3.513 3.513 0 0 0 5.842.765.75.75 0 1 1 1.142.972A5.013 5.013 0 0 1 8 15Zm4-13C6.477 2 2 6.477 2 12s4.477 10 10 10 10-4.477 10-10S17.523 2 12 2Zm8.5 10a8.5 8.5 0 1 1-17 0 8.5 8.5 0 0 1 17 0Z" fill="#F2C511"/></svg>

After

Width:  |  Height:  |  Size: 609 B

View File

@@ -0,0 +1 @@
<svg width="48" height="48" fill="none" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M8.25 4a.75.75 0 0 1 .743.648L9 4.75v2.773l1.874 2.815a.75.75 0 0 1 .117.306l.009.11v4.496a.75.75 0 0 1-.649.743L10.25 16H8.996v3.254a.75.75 0 0 1-1.492.101l-.007-.101L7.496 16 5.5 15.999v3.258a.75.75 0 0 1-1.493.101l-.006-.101L4 15.999 2.75 16a.75.75 0 0 1-.742-.648l-.007-.102v-4.496a.75.75 0 0 1 .071-.32l.055-.096 1.874-2.815V4.75a.75.75 0 0 1 1.493-.102l.007.102v3a.75.75 0 0 1-.072.32l-.054.096-1.874 2.815V14.5H9.5v-3.52L7.625 8.167a.75.75 0 0 1-.117-.306L7.5 7.75v-3A.75.75 0 0 1 8.25 4Zm7.004.001h4.496a.75.75 0 0 1 .743.649l.007.101L20.499 8h.75a.75.75 0 0 1 .744.648L22 8.75v4.496c0 .111-.025.22-.072.32l-.054.096L20 16.477v2.773a.75.75 0 0 1-1.494.102l-.006-.102v-3c0-.11.024-.22.071-.32l.054-.096L20.5 13.02V9.5h-5.998v3.52l1.874 2.814a.749.749 0 0 1 .118.306l.008.11v3a.75.75 0 0 1-1.493.102l-.007-.102v-2.773l-1.874-2.815a.75.75 0 0 1-.118-.306l-.008-.11V8.75a.75.75 0 0 1 .648-.743L13.752 8h.752V4.751a.75.75 0 0 1 .649-.743l.101-.007h4.496-4.496ZM19 5.501h-2.996V8h2.995V5.501Z" fill="#DDE6E8"/></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB