#include "main_widget.hpp"
#include <QCheckBox>
#include <QComboBox>
#include <QDebug>
#include <QDesktopWidget>
#include <QFileDialog>
#include <QGroupBox>
#include <QMessageBox>
#include <QMutexLocker>
#include <QPushButton>
#include <QRadioButton>
#include <QWeakPointer>
#include <qmath.h>
#include <cvb/device_factory.hpp>
MainWidget::MainWidget()
: QWidget(), gbStatEntriesLayout_(new QVBoxLayout),
pbSnap_(new QPushButton("Sna&p", this)),
chkGrab_(new QCheckBox("&Grab", this)),
gbSelectedPort_(new QGroupBox("Selected Port", this)),
gbStatistics_(new QGroupBox("Statistic", this)),
cbSelectedPort_(new QComboBox(gbSelectedPort_)),
view_(new
Cvb::UI::ImageView(this)),
device_(
Cvb::DeviceFactory::Open(
Cvb::InstallPath() +
CVB_LIT("drivers/CVMock.vin"),
Cvb::AcquisitionStack::Vin)),
streamH_(
Cvb::Async::SingleStreamHandler::Create(device_->Stream())),
updateStatTimer_(new QTimer(this)) {
qDebug() << "Please wait for the setup to load...";
QPushButton *pbOpen = new QPushButton("&Open Image", this);
QPushButton *pbOpenDev = new QPushButton("&Discover Devices", this);
QPushButton *pbSave = new QPushButton("&Save Image", this);
QHBoxLayout *mainLayout = new QHBoxLayout;
QVBoxLayout *sideLayout = new QVBoxLayout;
QVBoxLayout *gbSelectedPortLayout = new QVBoxLayout;
sideLayout->addWidget(pbOpen);
sideLayout->addWidget(pbOpenDev);
sideLayout->addWidget(pbSave);
sideLayout->addWidget(chkGrab_);
sideLayout->addWidget(pbSnap_);
onDiscover();
gbStatistics_->setLayout(gbStatEntriesLayout_);
sideLayout->addWidget(gbStatistics_);
sideLayout->addStretch();
gbSelectedPortLayout->addWidget(cbSelectedPort_);
gbSelectedPort_->setLayout(gbSelectedPortLayout);
sideLayout->addWidget(gbSelectedPort_);
mainLayout->addLayout(sideLayout);
mainLayout->addStretch();
mainLayout->addWidget(view_);
setLayout(mainLayout);
connect(pbOpen, SIGNAL(clicked()), this, SLOT(onOpen()));
connect(pbOpenDev, SIGNAL(clicked()), this, SLOT(onDiscover()));
connect(pbSave, SIGNAL(clicked()), this, SLOT(onSave()));
connect(pbSnap_, SIGNAL(clicked()), this, SLOT(onSnaped()));
connect(chkGrab_, SIGNAL(stateChanged(int)), this, SLOT(onGrabChanged(int)));
connect(cbSelectedPort_, SIGNAL(currentIndexChanged(int)), this,
SLOT(onPortIndexChanged(const int)));
connect(updateStatTimer_, SIGNAL(timeout()), SLOT(updateStatistics()));
updateStatTimer_->start(100);
view_->SetUploadMode(Cvb::UI::UploadMode::Viewport);
view_->SetRenderEngine(Cvb::UI::RenderEngine::Raster);
view_->Refresh(device_->DeviceImage(), Cvb::UI::AutoRefresh::On);
view_->SetWaitForRepaintEnabled(false);
initalizeTooltip();
}
MainWidget::~MainWidget() {
streamH_->Finish();
}
void MainWidget::onGrabChanged(int state) {
state == Qt::Unchecked ? streamH_->Finish() : streamH_->Run();
}
void MainWidget::onOpen() {
SignalGuard guard(this);
try {
if (streamH_->IsActive()) {
streamH_->Finish();
chkGrab_->setChecked(false);
}
QString filename = QFileDialog::getOpenFileName(
this, tr("Open Image"), QString("/"),
tr("CImages (*.bmp *.jpg *.png *.tif *.tiff)"));
if (!filename.isEmpty()) {
if (img)
img.reset();
view_->Refresh(img, Cvb::UI::RefreshMode::UploadAndScheduleRepaint,
Cvb::UI::AutoRefresh::Off);
}
std::cout << e.what() << "\nError opening image!" << std::endl;
}
}
void MainWidget::onDiscover() {
SignalGuard guard(this);
std::cout << "Discovering devices..." << std::endl;
discover_ =
cbSelectedPort_->clear();
gbSelectedPort_->setEnabled(true);
for (const auto &device : discover_) {
if (device.TryGetProperty(Cvb::Driver::DiscoveryProperties::DeviceModel,
devModel))
cbSelectedPort_->addItem(QString::fromStdString(devModel),
static_cast<int32_t>(device.Index()));
else
cbSelectedPort_->addItem(QString("Device %1").arg(device.Index()),
static_cast<int32_t>(device.Index()));
}
cbSelectedPort_->setCurrentIndex(0);
loadDiscoveredDevice(0ul);
}
void MainWidget::onSave() {
SignalGuard guard(this);
if (streamH_->IsActive()) {
streamH_->Finish();
chkGrab_->setChecked(false);
}
QString filename = QFileDialog::getSaveFileName(
this, tr("Save Image"), QString("~/"),
tr("CImages (*.bmp *.jpg *.png *.tif *.tiff)"));
if (!filename.isEmpty())
view_->Image()->Save(filename.toLatin1().toStdString());
}
void MainWidget::onSnaped() {
if (streamH_->IsActive()) {
streamH_->Finish();
chkGrab_->setChecked(false);
}
auto waitResult = device_->Stream()->GetSnapshot();
if (waitResult.Image == nullptr)
throw std::runtime_error("Could not snap image.");
}
void MainWidget::onPortIndexChanged(const int index) {
loadDiscoveredDevice(index);
}
void MainWidget::loadDiscoveredDevice(const unsigned long devNum) {
SignalGuard guard(this);
std::cout << "Loading device..." << std::endl;
if (streamH_->IsActive()) {
streamH_->Finish();
chkGrab_->setChecked(false);
}
try {
discover_.at(devNum).AccessToken(), Cvb::AcquisitionStack::Vin)};
if (tmpDevPtr) {
std::cout << "Loading device " << discover_.at(devNum).AccessToken()
<< std::endl;
streamH_.reset();
device_.reset();
device_ = tmpDevPtr;
view_->Refresh(device_->DeviceImage(), Cvb::UI::AutoRefresh::On);
initializeStatistics();
}
std::cout << e.what() << "\nError changing discovered device!" << std::endl;
}
}
void MainWidget::updateStatistics() {
SignalGuard guard(this);
unsigned long currentStat = 0;
for (auto const &stat : statisticsList_) {
auto const statEnumName = std::get<0>(stat);
auto value = device_->Stream()->Statistics(statEnumName);
auto statValue = QString::number(value);
statValues_.at(currentStat)->setText(statValue);
++currentStat;
}
}
void MainWidget::initializeStatistics() {
std::cout << "Creating device statistic..." << std::endl;
for (auto &valWdg : statValues_) {
gbStatEntriesLayout_->removeWidget(valWdg);
delete valWdg;
}
for (auto &nameWdg : statNames_) {
gbStatEntriesLayout_->removeWidget(nameWdg);
delete nameWdg;
}
for (auto &lay : gbHStatNameValLayout_) {
gbStatEntriesLayout_->removeItem(lay);
delete lay;
}
statisticsList_.clear();
statisticsList_.push_back(
tuple_element(StreamInfo::IsCameraDetected, "IsCameraDetected"));
statisticsList_.push_back(
tuple_element(StreamInfo::NumBuffersAcquired, "NumBuffersAcquired"));
statisticsList_.push_back(
tuple_element(StreamInfo::NumBuffersAnnounced, "NumBuffersAnnounced"));
statisticsList_.push_back(
tuple_element(StreamInfo::NumBuffersPending, "NumBuffersPending"));
statisticsList_.push_back(tuple_element(StreamInfo::NumBuffersBeingFilled,
"NumBuffersBeingFilled"));
statisticsList_.push_back(
tuple_element(StreamInfo::NumBuffersDelivered, "NumBuffersDelivered"));
statisticsList_.push_back(
tuple_element(StreamInfo::NumBuffersLocked, "NumBuffersLocked"));
statisticsList_.push_back(
tuple_element(StreamInfo::NumBuffersLost, "NumBuffersLost"));
statisticsList_.push_back(
tuple_element(StreamInfo::NumBuffersLostLocked, "NumBuffersLostLocked"));
statisticsList_.push_back(tuple_element(StreamInfo::NumBuffersLostTransfer,
"NumBuffersLostTransfer"));
statisticsList_.push_back(
tuple_element(StreamInfo::NumBuffersQueued, "NumBuffersQueued"));
statisticsList_.push_back(
tuple_element(StreamInfo::NumPacketsReceived, "NumPacketsReceived"));
statisticsList_.push_back(
tuple_element(StreamInfo::NumResends, "NumResends"));
statisticsList_.push_back(
tuple_element(StreamInfo::NumTriggersLost, "NumTriggersLost"));
statNames_.clear();
statValues_.clear();
gbHStatNameValLayout_.clear();
unsigned long currentStat = 0;
int unavailableStatisticPos = -1;
std::vector<int> delEntries{};
for (auto const &stat : statisticsList_) {
try {
++unavailableStatisticPos;
auto const statEnumName = std::get<0>(stat);
auto value = device_->Stream()->Statistics(
statEnumName);
std::string statValue = std::to_string(value);
statValues_.push_back(new QLabel(tr(statValue.c_str())));
statValues_.back()->setAlignment(Qt::AlignLeft);
statValues_.back()->updatesEnabled();
statNames_.push_back(new QLabel(tr(std::get<1>(stat).c_str())));
gbHStatNameValLayout_.push_back(new QHBoxLayout);
gbHStatNameValLayout_.at(currentStat)->addWidget(statNames_.back());
statValues_.back()->setAlignment(Qt::AlignRight);
gbHStatNameValLayout_.at(currentStat)->addWidget(statValues_.back());
gbStatEntriesLayout_->addLayout(gbHStatNameValLayout_.at(currentStat));
++currentStat;
} catch (const std::exception &e) {
std::cout << "Removing statistic due to error: " << e.what() << std::endl;
delEntries.push_back(unavailableStatisticPos);
}
}
for (auto ri = delEntries.rbegin(); ri != delEntries.rend(); ++ri)
statisticsList_.erase(statisticsList_.begin() + *ri);
std::cout << "Done initializing" << std::endl;
}
void MainWidget::initalizeTooltip() {
view_->setMouseTracking(true);
QApplication::setOverrideCursor(Qt::ArrowCursor);
view_->RegisterEventMouseMoved(
if (pixelVal.size() == 3) {
titleStream <<
"(X:" << mousePos.
X() <<
", Y:" << mousePos.
Y()
<< ") (R:" << qFloor(pixelVal[0])
<< ", G:" << qFloor(pixelVal[1])
<< ", B:" << qFloor(pixelVal[2]) << ")";
} else if (pixelVal.size() == 1) {
titleStream <<
"(X:" << mousePos.
X() <<
", Y:" << mousePos.
Y()
<< ") (Mono:" << qFloor(pixelVal[0]) << ")";
} else {
titleStream <<
"(X:" << mousePos.
X() <<
", Y:" << mousePos.
Y()
<< ") (Mono:";
for (auto &pix : pixelVal)
titleStream << qFloor(pix) << " | ";
titleStream << ")";
}
view_->setToolTip(QString::fromStdString(titleStream.str()));
});
}
void MainWidget::blockUI(const bool block) {
chkGrab_->blockSignals(block);
pbSnap_->blockSignals(block);
cbSelectedPort_->blockSignals(block);
view_->blockSignals(block);
gbSelectedPort_->blockSignals(block);
gbStatistics_->blockSignals(block);
updateStatTimer_->blockSignals(block);
}
static std::vector< DiscoveryInformation > Discover()
static std::shared_ptr< T > Open(const String &provider, AcquisitionStack acquisitionStack=AcquisitionStack::PreferVin)
static std::unique_ptr< Image > Load(const String &fileName)
static std::unique_ptr< SingleStreamHandler > Create(const Driver::StreamPtr &stream)
std::stringstream StringStream
std::shared_ptr< Device > DevicePtr