Compare commits

...

5 commits

Author SHA1 Message Date
Carl Philipp Klemm
b6fb6ca7d4 Put the file name of the code editor into the satus bar instead of the title bar 2025-10-13 15:32:47 +02:00
Carl Philipp Klemm
73aa61a13b Merge remote-tracking branch 'uvos/actions' 2025-10-13 15:24:02 +02:00
Carl Philipp Klemm
8ad659de76 Add example generation 2025-10-13 15:21:17 +02:00
5e91fd4a1a Add keyboard shortcuts 2025-10-13 14:51:28 +02:00
2d58946f3f Implement actions 2025-10-13 14:28:34 +02:00
2 changed files with 149 additions and 6 deletions

View file

@ -1,6 +1,10 @@
#include <eismultiplexer.h> #include <eismultiplexer.h>
#include <QMessageBox> #include <QMessageBox>
#include <QMessageBox> #include <QMessageBox>
#include <set>
#include <QFileDialog>
#include <QTextStream>
#include <QFile>
#include "mainwindow.h" #include "mainwindow.h"
#include "ui_mainwindow.h" #include "ui_mainwindow.h"
#include "triggerwidget.h" #include "triggerwidget.h"
@ -8,7 +12,9 @@
MainWindow::MainWindow(QWidget *parent): MainWindow::MainWindow(QWidget *parent):
QMainWindow(parent), QMainWindow(parent),
ui(new Ui::MainWindow), ui(new Ui::MainWindow),
codeEditor(this) codeEditor(this),
currentFilePath(""),
isFileModified(false)
{ {
ui->setupUi(this); ui->setupUi(this);
enumerateDevices(); enumerateDevices();
@ -23,7 +29,22 @@ MainWindow::MainWindow(QWidget *parent):
ui->codeLayout->addWidget(&codeEditor); ui->codeLayout->addWidget(&codeEditor);
// Set up keyboard shortcuts
ui->actionOpen->setShortcut(QKeySequence::Open);
ui->actionSave->setShortcut(QKeySequence::Save);
ui->actionSave_As->setShortcut(QKeySequence::SaveAs);
ui->actionQuit->setShortcut(QKeySequence::Quit);
connect(ui->actionQuit, &QAction::triggered, this, [this]() {close();}); connect(ui->actionQuit, &QAction::triggered, this, [this]() {close();});
connect(ui->actionOpen, &QAction::triggered, this, &MainWindow::onActionOpenTriggered);
connect(ui->actionSave, &QAction::triggered, this, &MainWindow::onActionSaveTriggered);
connect(ui->actionSave_As, &QAction::triggered, this, &MainWindow::onActionSaveAsTriggered);
// Connect text changed signal to track modifications
connect(&codeEditor, &QTextEdit::textChanged, this, [this]() {
isFileModified = true;
updateStatus();
});
} }
MainWindow::~MainWindow() MainWindow::~MainWindow()
@ -31,6 +52,90 @@ MainWindow::~MainWindow()
delete ui; delete ui;
} }
void MainWindow::updateStatus()
{
if (!currentFilePath.isEmpty()) {
QString status = "EisMultiplexer-Qt";
status = QString("%1").arg(currentFilePath);
if (isFileModified) {
status += " - [Unsaved Changes]";
}
ui->statusbar->showMessage(status);
}
}
void MainWindow::onActionOpenTriggered()
{
QString filePath = QFileDialog::getOpenFileName(this, tr("Open Python Script"),
"",
tr("Python Files (*.py);;All Files (*)"));
if (filePath.isEmpty()) {
return;
}
QFile file(filePath);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
QMessageBox::warning(this, tr("Error"), tr("Could not open file: %1").arg(filePath));
return;
}
QTextStream in(&file);
QString content = in.readAll();
file.close();
codeEditor.setPlainText(content);
currentFilePath = filePath;
isFileModified = false;
updateStatus();
}
void MainWindow::onActionSaveTriggered()
{
if (currentFilePath.isEmpty()) {
onActionSaveAsTriggered();
return;
}
QFile file(currentFilePath);
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
QMessageBox::warning(this, tr("Error"), tr("Could not save file: %1").arg(currentFilePath));
return;
}
QTextStream out(&file);
out << codeEditor.toPlainText();
file.close();
isFileModified = false;
updateStatus();
}
void MainWindow::onActionSaveAsTriggered()
{
QString filePath = QFileDialog::getSaveFileName(this, tr("Save Python Script"),
"",
tr("Python Files (*.py);;All Files (*)"));
if (filePath.isEmpty()) {
return;
}
QFile file(filePath);
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
QMessageBox::warning(this, tr("Error"), tr("Could not save file: %1").arg(filePath));
return;
}
QTextStream out(&file);
out << codeEditor.toPlainText();
file.close();
currentFilePath = filePath;
isFileModified = false;
updateStatus();
}
void MainWindow::enumerateDevices() void MainWindow::enumerateDevices()
{ {
size_t count = 0; size_t count = 0;
@ -114,17 +219,47 @@ void MainWindow::enumerateDevices()
ui->statusbar->showMessage("Ready"); ui->statusbar->showMessage("Ready");
free(serials); free(serials);
generateExample();
} }
void MainWindow::generateExample() void MainWindow::generateExample()
{ {
QString example = QString example =
"import eismultiplexer\n\n" "# This is an example script to show you how\n# to drive eismultiplexer using the python api\n"
"from time import sleep"; "import eismultiplexer as multi\n"
"from time import sleep\n\n"
"# First initalize the device(s)\n";
for (const auto& channel : channels) std::set<uint16_t> serials;
for (size_t i = 0; i < channels.size(); ++i)
serials.insert(channels[i]->getDeviceSerial());
size_t i = 0;
for (uint16_t serial : serials)
{ {
example.append(QString("eismultiplexer")); example.append(QString("multiplexer_") + QString::number(i) + " multi.Multiplexer(serial=" + QString::number(serial) + ")\n");
} ++i;
}
example.append("\nprint('\\nListing the nummber of channels per unit')\n");
for (size_t i = 0; i < serials.size(); ++i)
{
QString printLine = "print(f'Found unit with serial number {" + QString::number(channels[i]->getDeviceSerial()) + "} and {multiplexer_" + QString::number(i) + ".getChannelCount()} channels')\n";
example.append(printLine);
}
example.append("\nprint('Connecting the first and second channel on the first unit')\n");
example.append("multiplexer_0.connectChannel(multi.Channel.A)\n");
example.append("multiplexer_0.connectChannel(multi.Channel.B)\n\n");
example.append("print('Waiting for half a second for something to happen')\n");
example.append("sleep(0.5)\n\n");
example.append("print('Disconnect first channel')\n");
example.append("multiplexer_0.disconnectChannel(multi.Channel.A)\n\n");
example.append("print('Waiting up to 5000 milliseconds for a trigger')\n");
example.append("multiplexer_0.setTriggerState(0, multi.TriggerState.INPUT)\n");
example.append("multiplexer_0.waitTrigger(0, multi.TriggerState.HIGHLEVEL, 5000)\n\n");
example.append("print('Disconnecting all channels')\n");
example.append("multiplexer_0.clear()\n");
codeEditor.setText(example);
} }

View file

@ -34,9 +34,17 @@ public:
explicit MainWindow(QWidget *parent = nullptr); explicit MainWindow(QWidget *parent = nullptr);
~MainWindow(); ~MainWindow();
private slots:
void onActionOpenTriggered();
void onActionSaveTriggered();
void onActionSaveAsTriggered();
private: private:
void enumerateDevices(); void enumerateDevices();
void generateExample(); void generateExample();
void updateStatus();
QString currentFilePath;
bool isFileModified;
}; };
#endif // MAINWINDOW_H #endif // MAINWINDOW_H