initial commit
This commit is contained in:
		
						commit
						b585be3679
					
				
					 9 changed files with 561 additions and 0 deletions
				
			
		
							
								
								
									
										76
									
								
								CMakeLists.txt
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								CMakeLists.txt
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,76 @@
 | 
			
		|||
cmake_minimum_required(VERSION 3.5)
 | 
			
		||||
 | 
			
		||||
project(QImageTagger VERSION 0.1 LANGUAGES CXX)
 | 
			
		||||
 | 
			
		||||
set(CMAKE_AUTOUIC ON)
 | 
			
		||||
set(CMAKE_AUTOMOC ON)
 | 
			
		||||
set(CMAKE_AUTORCC ON)
 | 
			
		||||
 | 
			
		||||
set(CMAKE_CXX_STANDARD 17)
 | 
			
		||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
 | 
			
		||||
 | 
			
		||||
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets)
 | 
			
		||||
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets)
 | 
			
		||||
 | 
			
		||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
 | 
			
		||||
 | 
			
		||||
set(PROJECT_SOURCES
 | 
			
		||||
	main.cpp
 | 
			
		||||
	mainwindow.cpp
 | 
			
		||||
	mainwindow.h
 | 
			
		||||
	mainwindow.ui
 | 
			
		||||
	imagemeta.h
 | 
			
		||||
	imagemeta.cpp
 | 
			
		||||
	imagewidget.h
 | 
			
		||||
	imagewidget.cpp
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
 | 
			
		||||
	qt_add_executable(QImageTagger
 | 
			
		||||
		MANUAL_FINALIZATION
 | 
			
		||||
		${PROJECT_SOURCES}
 | 
			
		||||
    )
 | 
			
		||||
# Define target properties for Android with Qt 6 as:
 | 
			
		||||
#    set_property(TARGET QImageTagger APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR
 | 
			
		||||
#                 ${CMAKE_CURRENT_SOURCE_DIR}/android)
 | 
			
		||||
# For more information, see https://doc.qt.io/qt-6/qt-add-executable.html#target-creation
 | 
			
		||||
else()
 | 
			
		||||
	if(ANDROID)
 | 
			
		||||
		add_library(QImageTagger SHARED
 | 
			
		||||
			${PROJECT_SOURCES}
 | 
			
		||||
		)
 | 
			
		||||
# Define properties for Android with Qt 5 after find_package() calls as:
 | 
			
		||||
#    set(ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/android")
 | 
			
		||||
else()
 | 
			
		||||
	add_executable(QImageTagger
 | 
			
		||||
		${PROJECT_SOURCES}
 | 
			
		||||
	)
 | 
			
		||||
endif()
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
target_link_libraries(QImageTagger PRIVATE Qt${QT_VERSION_MAJOR}::Widgets)
 | 
			
		||||
 | 
			
		||||
# Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1.
 | 
			
		||||
# If you are developing for iOS or macOS you should consider setting an
 | 
			
		||||
# explicit, fixed bundle identifier manually though.
 | 
			
		||||
if(${QT_VERSION} VERSION_LESS 6.1.0)
 | 
			
		||||
	set(BUNDLE_ID_OPTION MACOSX_BUNDLE_GUI_IDENTIFIER com.example.QImageTagger)
 | 
			
		||||
endif()
 | 
			
		||||
set_target_properties(QImageTagger PROPERTIES
 | 
			
		||||
	${BUNDLE_ID_OPTION}
 | 
			
		||||
	MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
 | 
			
		||||
	MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
 | 
			
		||||
	MACOSX_BUNDLE TRUE
 | 
			
		||||
	WIN32_EXECUTABLE TRUE
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
include(GNUInstallDirs)
 | 
			
		||||
install(TARGETS QImageTagger
 | 
			
		||||
	BUNDLE DESTINATION .
 | 
			
		||||
	LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
 | 
			
		||||
	RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
if(QT_VERSION_MAJOR EQUAL 6)
 | 
			
		||||
	qt_finalize_executable(QImageTagger)
 | 
			
		||||
endif()
 | 
			
		||||
							
								
								
									
										20
									
								
								imagemeta.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								imagemeta.cpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,20 @@
 | 
			
		|||
#include "imagemeta.h"
 | 
			
		||||
 | 
			
		||||
ImageMeta::ImageMeta(const std::filesystem::path& path, const QString& text):
 | 
			
		||||
	path{path}, text{text}
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ImageMeta::ImageMeta(const QJsonObject& json, const std::filesystem::path& dir)
 | 
			
		||||
{
 | 
			
		||||
	QJsonValue filename = json["file_name"];
 | 
			
		||||
	if(filename == QJsonValue::Undefined || !filename.isString())
 | 
			
		||||
		throw ParseException("No or invalid file_name field found");
 | 
			
		||||
	path = dir/filename.toString().toStdString();
 | 
			
		||||
 | 
			
		||||
	QJsonValue textfrommeta = json["text"];
 | 
			
		||||
	text = textfrommeta.toString("");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										29
									
								
								imagemeta.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								imagemeta.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,29 @@
 | 
			
		|||
#ifndef IMAGEMETA_H
 | 
			
		||||
#define IMAGEMETA_H
 | 
			
		||||
 | 
			
		||||
#include <filesystem>
 | 
			
		||||
#include <QString>
 | 
			
		||||
#include <QJsonObject>
 | 
			
		||||
#include <QException>
 | 
			
		||||
 | 
			
		||||
class ParseException : public QException
 | 
			
		||||
{
 | 
			
		||||
	QString msg;
 | 
			
		||||
public:
 | 
			
		||||
	ParseException(const QString& msg): msg{msg} {}
 | 
			
		||||
	QString getMesg() {return msg;};
 | 
			
		||||
	void raise() const override { throw *this; }
 | 
			
		||||
	ParseException *clone() const override { return new ParseException(*this); }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class ImageMeta
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	std::filesystem::path path;
 | 
			
		||||
	QString text;
 | 
			
		||||
 | 
			
		||||
	ImageMeta(const std::filesystem::path& path, const QString& text = "");
 | 
			
		||||
	ImageMeta(const QJsonObject& json, const std::filesystem::path& dir);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // IMAGEMETA_H
 | 
			
		||||
							
								
								
									
										39
									
								
								imagewidget.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								imagewidget.cpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,39 @@
 | 
			
		|||
#include <QPainter>
 | 
			
		||||
 | 
			
		||||
#include "imagewidget.h"
 | 
			
		||||
 | 
			
		||||
void ImageWidget::paintEvent(QPaintEvent *event)
 | 
			
		||||
{
 | 
			
		||||
	QLabel::paintEvent(event);
 | 
			
		||||
	displayImage();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ImageWidget::setPixmap(QPixmap image)
 | 
			
		||||
{
 | 
			
		||||
	sourceImage = image;
 | 
			
		||||
	currentImage = image;
 | 
			
		||||
	repaint();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ImageWidget::displayImage()
 | 
			
		||||
{
 | 
			
		||||
	if (sourceImage.isNull())
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	float cw = width(), ch = height();
 | 
			
		||||
	float pw = currentImage.width(), ph = currentImage.height();
 | 
			
		||||
 | 
			
		||||
	if(pw > cw && ph > ch && pw/cw > ph/ch ||
 | 
			
		||||
		pw > cw && ph <= ch ||
 | 
			
		||||
		pw < cw && ph < ch && cw/pw < ch/ph)
 | 
			
		||||
		currentImage = sourceImage.scaledToWidth(cw, Qt::TransformationMode::FastTransformation);
 | 
			
		||||
	else if(pw > cw && ph > ch && pw/cw <= ph/ch ||
 | 
			
		||||
			ph > ch && pw <= cw ||
 | 
			
		||||
			pw < cw && ph < ch && cw/pw > ch/ph)
 | 
			
		||||
		currentImage = sourceImage.scaledToHeight(ch, Qt::TransformationMode::FastTransformation);
 | 
			
		||||
 | 
			
		||||
	int x = (cw - currentImage.width())/2, y = (ch - currentImage.height())/2;
 | 
			
		||||
 | 
			
		||||
	QPainter paint(this);
 | 
			
		||||
	paint.drawPixmap(x, y, currentImage);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										18
									
								
								imagewidget.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								imagewidget.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,18 @@
 | 
			
		|||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <QPixmap>
 | 
			
		||||
#include <QLabel>
 | 
			
		||||
 | 
			
		||||
class ImageWidget: public QLabel
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
    QPixmap sourceImage;
 | 
			
		||||
    QPixmap currentImage;
 | 
			
		||||
 | 
			
		||||
    void displayImage();
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    ImageWidget(QWidget* parent): QLabel(parent) { }
 | 
			
		||||
    void setPixmap(QPixmap image);
 | 
			
		||||
    void paintEvent(QPaintEvent *event);
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										11
									
								
								main.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								main.cpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,11 @@
 | 
			
		|||
#include "mainwindow.h"
 | 
			
		||||
 | 
			
		||||
#include <QApplication>
 | 
			
		||||
 | 
			
		||||
int main(int argc, char *argv[])
 | 
			
		||||
{
 | 
			
		||||
	QApplication a(argc, argv);
 | 
			
		||||
	MainWindow w;
 | 
			
		||||
	w.show();
 | 
			
		||||
	return a.exec();
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										173
									
								
								mainwindow.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										173
									
								
								mainwindow.cpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,173 @@
 | 
			
		|||
#include "mainwindow.h"
 | 
			
		||||
#include "./ui_mainwindow.h"
 | 
			
		||||
 | 
			
		||||
#include <QFileDialog>
 | 
			
		||||
#include <QMessageBox>
 | 
			
		||||
#include <QJsonDocument>
 | 
			
		||||
 | 
			
		||||
MainWindow::MainWindow(QWidget *parent)
 | 
			
		||||
	: QMainWindow(parent)
 | 
			
		||||
	, ui(new Ui::MainWindow)
 | 
			
		||||
{
 | 
			
		||||
	ui->setupUi(this);
 | 
			
		||||
	connect(ui->actionOpen, &QAction::triggered, this, [this](bool){open();});
 | 
			
		||||
	connect(ui->nextButton, &QPushButton::clicked, this, [this](bool){setImage(index+1);});
 | 
			
		||||
	connect(ui->prevButton, &QPushButton::clicked, this, [this](bool){setImage(index-1);});
 | 
			
		||||
	connect(ui->actionSave, &QAction::triggered, this, [this](bool){save();});
 | 
			
		||||
	connect(ui->actionQuit, &QAction::triggered, this, [this](bool){close();});
 | 
			
		||||
	ui->verticalLayout->addWidget(&status);
 | 
			
		||||
	ui->imageLabel->setScaledContents( true );
 | 
			
		||||
	ui->imageLabel->setSizePolicy( QSizePolicy::Ignored, QSizePolicy::Ignored );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MainWindow::~MainWindow()
 | 
			
		||||
{
 | 
			
		||||
	delete ui;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MainWindow::open()
 | 
			
		||||
{
 | 
			
		||||
	QString dirpath = QFileDialog::getExistingDirectory(this, "Choose a directory with images", "", QFlags<QFileDialog::Option>());
 | 
			
		||||
	if(dirpath.isEmpty())
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	openDir(dirpath.toStdString());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MainWindow::openDir(const std::filesystem::path& path)
 | 
			
		||||
{
 | 
			
		||||
	imageMetas.clear();
 | 
			
		||||
 | 
			
		||||
	QDir dir(path);
 | 
			
		||||
	bool hasMetadata = false;
 | 
			
		||||
	std::vector<std::filesystem::path> imagePaths;
 | 
			
		||||
	for(QString filename : dir.entryList(QDir::Files))
 | 
			
		||||
	{
 | 
			
		||||
		if(filename == "metadata.jsonl")
 | 
			
		||||
			hasMetadata = true;
 | 
			
		||||
		else if(filename.endsWith(".jpg") || filename.endsWith(".png"))
 | 
			
		||||
			imagePaths.push_back(path/filename.toStdString());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if(imagePaths.empty())
 | 
			
		||||
	{
 | 
			
		||||
		QMessageBox::warning(this, "No images found", "No valid images found in this directory");
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if(hasMetadata)
 | 
			
		||||
	{
 | 
			
		||||
		if(!loadMetadata(path/"metadata.jsonl"))
 | 
			
		||||
			QMessageBox::warning(this, "Could not read",
 | 
			
		||||
								 (std::string("Could not read ") + path.string() + std::string("/metadata.jsonl, file contains errors")).c_str());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for(const std::filesystem::path &path : imagePaths)
 | 
			
		||||
	{
 | 
			
		||||
		if(imageIsKnown(path))
 | 
			
		||||
			continue;
 | 
			
		||||
		qDebug()<<path.c_str()<<"not in existing metadata.jsonl";
 | 
			
		||||
		imageMetas.push_back(ImageMeta(path));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this->dir = path;
 | 
			
		||||
 | 
			
		||||
	ui->textEdit->document()->setPlainText(imageMetas[0].text);
 | 
			
		||||
	setImage(0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MainWindow::setImage(ssize_t index)
 | 
			
		||||
{
 | 
			
		||||
	if(imageMetas.empty())
 | 
			
		||||
		return;
 | 
			
		||||
	else if(index > imageMetas.size()-1)
 | 
			
		||||
			return;
 | 
			
		||||
	else if(index < 0)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	imageMetas[this->index].text = ui->textEdit->document()->toPlainText();
 | 
			
		||||
	this->index = index;
 | 
			
		||||
	ui->counterLabel->setText(QString::asprintf("%04zu/%04zu", index, imageMetas.size()-1));
 | 
			
		||||
	ui->textEdit->document()->setPlainText(imageMetas[index].text);
 | 
			
		||||
 | 
			
		||||
	QPixmap image;
 | 
			
		||||
	bool ret = image.load(imageMetas[index].path.string().c_str());
 | 
			
		||||
	if(!ret)
 | 
			
		||||
	{
 | 
			
		||||
		ui->imageLabel->setPixmap(QPixmap());
 | 
			
		||||
		ui->imageLabel->setText(("Unable to load " + imageMetas[index].path.string()).c_str());
 | 
			
		||||
		ui->imageLabel->setText("No image loaded");
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		ui->imageLabel->setPixmap(image);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ui->imageLabel->setText("");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool MainWindow::loadMetadata(const std::filesystem::path& path)
 | 
			
		||||
{
 | 
			
		||||
	QFile meta(path);
 | 
			
		||||
	meta.open(QIODeviceBase::ReadOnly);
 | 
			
		||||
	if(!meta.isOpen())
 | 
			
		||||
	{
 | 
			
		||||
		qWarning()<<("Could not open " + path.string()).c_str();
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	QByteArray line = meta.readLine();
 | 
			
		||||
	while(!line.isEmpty())
 | 
			
		||||
	{
 | 
			
		||||
		QJsonParseError error;
 | 
			
		||||
		QJsonDocument json = QJsonDocument::fromJson(line, &error);
 | 
			
		||||
		if(json.isNull())
 | 
			
		||||
		{
 | 
			
		||||
			qWarning()<<error.errorString();
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		imageMetas.push_back(ImageMeta(json.object(), path.parent_path()));
 | 
			
		||||
		line = meta.readLine();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool MainWindow::imageIsKnown(const std::filesystem::path& path)
 | 
			
		||||
{
 | 
			
		||||
	for(const ImageMeta& meta : imageMetas)
 | 
			
		||||
	{
 | 
			
		||||
		if(meta.path == path)
 | 
			
		||||
			return true;
 | 
			
		||||
	}
 | 
			
		||||
	return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MainWindow::save()
 | 
			
		||||
{
 | 
			
		||||
	if(imageMetas.empty())
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	QFile file(dir/"metadata.jsonl");
 | 
			
		||||
	if(!file.open(QIODeviceBase::WriteOnly | QIODeviceBase::Truncate))
 | 
			
		||||
	{
 | 
			
		||||
		QMessageBox::warning(this, "Could not save",
 | 
			
		||||
							 ("Could not save, can not open " + (dir/"metadata.jsonl").string() + " for writeing").c_str());
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for(const ImageMeta& meta : imageMetas)
 | 
			
		||||
	{
 | 
			
		||||
		QJsonObject obj;
 | 
			
		||||
		obj["file_name"] = std::filesystem::relative(meta.path, dir).string().c_str();
 | 
			
		||||
		obj["text"] = meta.text;
 | 
			
		||||
		QJsonDocument document(obj);
 | 
			
		||||
		QByteArray json = document.toJson(QJsonDocument::Compact);
 | 
			
		||||
		json.removeIf([](char ch){return ch == '\n';});
 | 
			
		||||
		json.append('\n');
 | 
			
		||||
		file.write(json);
 | 
			
		||||
	}
 | 
			
		||||
	file.close();
 | 
			
		||||
	QMessageBox::information(this, "Saved", ("Saved to " + (dir/"metadata.jsonl").string()).c_str());
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										42
									
								
								mainwindow.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								mainwindow.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,42 @@
 | 
			
		|||
#ifndef MAINWINDOW_H
 | 
			
		||||
#define MAINWINDOW_H
 | 
			
		||||
 | 
			
		||||
#include <QMainWindow>
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <QStatusBar>
 | 
			
		||||
 | 
			
		||||
#include "imagemeta.h"
 | 
			
		||||
 | 
			
		||||
QT_BEGIN_NAMESPACE
 | 
			
		||||
namespace Ui {
 | 
			
		||||
class MainWindow;
 | 
			
		||||
}
 | 
			
		||||
QT_END_NAMESPACE
 | 
			
		||||
 | 
			
		||||
class MainWindow : public QMainWindow
 | 
			
		||||
{
 | 
			
		||||
	Q_OBJECT
 | 
			
		||||
 | 
			
		||||
	bool modified = false;
 | 
			
		||||
	std::vector<ImageMeta> imageMetas;
 | 
			
		||||
	size_t index = 0;
 | 
			
		||||
	std::filesystem::path dir;
 | 
			
		||||
	QStatusBar status;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
	MainWindow(QWidget *parent = nullptr);
 | 
			
		||||
	~MainWindow();
 | 
			
		||||
 | 
			
		||||
private slots:
 | 
			
		||||
	void open();
 | 
			
		||||
	void save();
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	void openDir(const std::filesystem::path& path);
 | 
			
		||||
	bool loadMetadata(const std::filesystem::path& path);
 | 
			
		||||
	bool imageIsKnown(const std::filesystem::path& path);
 | 
			
		||||
	void setImage(ssize_t index);
 | 
			
		||||
 | 
			
		||||
	Ui::MainWindow *ui;
 | 
			
		||||
};
 | 
			
		||||
#endif // MAINWINDOW_H
 | 
			
		||||
							
								
								
									
										153
									
								
								mainwindow.ui
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										153
									
								
								mainwindow.ui
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,153 @@
 | 
			
		|||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<ui version="4.0">
 | 
			
		||||
 <class>MainWindow</class>
 | 
			
		||||
 <widget class="QMainWindow" name="MainWindow">
 | 
			
		||||
  <property name="geometry">
 | 
			
		||||
   <rect>
 | 
			
		||||
    <x>0</x>
 | 
			
		||||
    <y>0</y>
 | 
			
		||||
    <width>1074</width>
 | 
			
		||||
    <height>692</height>
 | 
			
		||||
   </rect>
 | 
			
		||||
  </property>
 | 
			
		||||
  <property name="windowTitle">
 | 
			
		||||
   <string>QImageTagger</string>
 | 
			
		||||
  </property>
 | 
			
		||||
  <widget class="QWidget" name="centralwidget">
 | 
			
		||||
   <layout class="QVBoxLayout" name="verticalLayout_2">
 | 
			
		||||
    <item>
 | 
			
		||||
     <layout class="QVBoxLayout" name="verticalLayout" stretch="1,0,0">
 | 
			
		||||
      <property name="spacing">
 | 
			
		||||
       <number>0</number>
 | 
			
		||||
      </property>
 | 
			
		||||
      <property name="bottomMargin">
 | 
			
		||||
       <number>0</number>
 | 
			
		||||
      </property>
 | 
			
		||||
      <item>
 | 
			
		||||
       <widget class="ImageWidget" name="imageLabel">
 | 
			
		||||
        <property name="font">
 | 
			
		||||
         <font>
 | 
			
		||||
          <pointsize>24</pointsize>
 | 
			
		||||
         </font>
 | 
			
		||||
        </property>
 | 
			
		||||
        <property name="text">
 | 
			
		||||
         <string>No image loaded</string>
 | 
			
		||||
        </property>
 | 
			
		||||
        <property name="alignment">
 | 
			
		||||
         <set>Qt::AlignmentFlag::AlignCenter</set>
 | 
			
		||||
        </property>
 | 
			
		||||
        <property name="margin">
 | 
			
		||||
         <number>10</number>
 | 
			
		||||
        </property>
 | 
			
		||||
       </widget>
 | 
			
		||||
      </item>
 | 
			
		||||
      <item>
 | 
			
		||||
       <widget class="QPlainTextEdit" name="textEdit"/>
 | 
			
		||||
      </item>
 | 
			
		||||
      <item>
 | 
			
		||||
       <layout class="QHBoxLayout" name="horizontalLayout">
 | 
			
		||||
        <property name="spacing">
 | 
			
		||||
         <number>0</number>
 | 
			
		||||
        </property>
 | 
			
		||||
        <property name="bottomMargin">
 | 
			
		||||
         <number>0</number>
 | 
			
		||||
        </property>
 | 
			
		||||
        <item>
 | 
			
		||||
         <widget class="QPushButton" name="prevButton">
 | 
			
		||||
          <property name="text">
 | 
			
		||||
           <string>Prev</string>
 | 
			
		||||
          </property>
 | 
			
		||||
          <property name="shortcut">
 | 
			
		||||
           <string>Left</string>
 | 
			
		||||
          </property>
 | 
			
		||||
         </widget>
 | 
			
		||||
        </item>
 | 
			
		||||
        <item>
 | 
			
		||||
         <widget class="QLabel" name="counterLabel">
 | 
			
		||||
          <property name="sizePolicy">
 | 
			
		||||
           <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
 | 
			
		||||
            <horstretch>0</horstretch>
 | 
			
		||||
            <verstretch>0</verstretch>
 | 
			
		||||
           </sizepolicy>
 | 
			
		||||
          </property>
 | 
			
		||||
          <property name="minimumSize">
 | 
			
		||||
           <size>
 | 
			
		||||
            <width>120</width>
 | 
			
		||||
            <height>0</height>
 | 
			
		||||
           </size>
 | 
			
		||||
          </property>
 | 
			
		||||
          <property name="text">
 | 
			
		||||
           <string>0000/0000</string>
 | 
			
		||||
          </property>
 | 
			
		||||
          <property name="alignment">
 | 
			
		||||
           <set>Qt::AlignmentFlag::AlignCenter</set>
 | 
			
		||||
          </property>
 | 
			
		||||
         </widget>
 | 
			
		||||
        </item>
 | 
			
		||||
        <item>
 | 
			
		||||
         <widget class="QPushButton" name="nextButton">
 | 
			
		||||
          <property name="text">
 | 
			
		||||
           <string>Next</string>
 | 
			
		||||
          </property>
 | 
			
		||||
          <property name="shortcut">
 | 
			
		||||
           <string>Right</string>
 | 
			
		||||
          </property>
 | 
			
		||||
         </widget>
 | 
			
		||||
        </item>
 | 
			
		||||
       </layout>
 | 
			
		||||
      </item>
 | 
			
		||||
     </layout>
 | 
			
		||||
    </item>
 | 
			
		||||
   </layout>
 | 
			
		||||
  </widget>
 | 
			
		||||
  <widget class="QMenuBar" name="menubar">
 | 
			
		||||
   <property name="geometry">
 | 
			
		||||
    <rect>
 | 
			
		||||
     <x>0</x>
 | 
			
		||||
     <y>0</y>
 | 
			
		||||
     <width>1074</width>
 | 
			
		||||
     <height>25</height>
 | 
			
		||||
    </rect>
 | 
			
		||||
   </property>
 | 
			
		||||
   <widget class="QMenu" name="menuFile">
 | 
			
		||||
    <property name="title">
 | 
			
		||||
     <string>File</string>
 | 
			
		||||
    </property>
 | 
			
		||||
    <addaction name="actionOpen"/>
 | 
			
		||||
    <addaction name="actionSave"/>
 | 
			
		||||
    <addaction name="actionQuit"/>
 | 
			
		||||
   </widget>
 | 
			
		||||
   <addaction name="menuFile"/>
 | 
			
		||||
  </widget>
 | 
			
		||||
  <action name="actionOpen">
 | 
			
		||||
   <property name="text">
 | 
			
		||||
    <string>Open</string>
 | 
			
		||||
   </property>
 | 
			
		||||
   <property name="shortcut">
 | 
			
		||||
    <string>Ctrl+O</string>
 | 
			
		||||
   </property>
 | 
			
		||||
  </action>
 | 
			
		||||
  <action name="actionQuit">
 | 
			
		||||
   <property name="text">
 | 
			
		||||
    <string>Quit</string>
 | 
			
		||||
   </property>
 | 
			
		||||
  </action>
 | 
			
		||||
  <action name="actionSave">
 | 
			
		||||
   <property name="text">
 | 
			
		||||
    <string>Save</string>
 | 
			
		||||
   </property>
 | 
			
		||||
   <property name="shortcut">
 | 
			
		||||
    <string>Ctrl+S</string>
 | 
			
		||||
   </property>
 | 
			
		||||
  </action>
 | 
			
		||||
 </widget>
 | 
			
		||||
 <customwidgets>
 | 
			
		||||
  <customwidget>
 | 
			
		||||
   <class>ImageWidget</class>
 | 
			
		||||
   <extends>QLabel</extends>
 | 
			
		||||
   <header>imagewidget.h</header>
 | 
			
		||||
  </customwidget>
 | 
			
		||||
 </customwidgets>
 | 
			
		||||
 <resources/>
 | 
			
		||||
 <connections/>
 | 
			
		||||
</ui>
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue