print-labels-gui/print-labels-gui.py

242 lines
8.2 KiB
Python
Raw Normal View History

#!/usr/bin/python3
"""
Скрипт с графическим интерфейсом
для печати этикеток на принтере серий brother p-touch,
на основе https://gitea.basealt.ru/polkovnikovaav/ptouch-print-labels
подробности и настройки в README.md
"""
from PySide6.QtWidgets import QApplication
from PySide6 import QtGui,QtWidgets
from PySide6.QtWidgets import QMainWindow, QWidget, QLabel,QVBoxLayout, QPushButton,QGridLayout,QLineEdit, QComboBox,QMessageBox
import subprocess
import time
import os
import sys
from PIL import Image, ImageOps, ImageDraw, ImageFont
from barcode import EAN13
from barcode.writer import ImageWriter
# главное окно
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.conf="barcode2-gui.ini"
self.setWindowTitle('Печать стикеров')
self.q_button_start = QPushButton('печать')
self.q_button_start.clicked.connect(self.start_print)
self.q_label1 = QLabel()
self.q_label2 = QLabel()
self.q_label3 = QLabel()
self.q_label1.setText("Введите текст:")
self.q_label2.setText("Введите SN (не вводить - генерация):")
self.q_label3.setText("Выберите тип устройства:")
self.q_combo = QComboBox(self)
self.q_combo.addItem("компьютер")
self.q_combo.addItem("монитор")
self.q_combo.addItem("сетевое об.")
self.q_combo.addItem("токен")
self.q_combo.addItem("принтер/МФУ")
self.q_combo.addItem("флешка")
self.q_combo.addItem("HID")
self.q_combo.addItem("UPS")
self.q_combo.addItem("другое")
self.q_button_start=QPushButton("печать")
self.q_button_start.setMinimumSize(20,80)
self.q_button_start.clicked.connect(self.start_print)
self.grid_layout = QGridLayout()
self.layout1 = QVBoxLayout()
self.q_edit1=QLineEdit() # текст (над ШК)
self.q_edit2=QLineEdit() # вводимый свой серийник (если не нужна генерациия)
self.q_edit3=QLineEdit() # выводимый SN для справки
self.q_edit3.setReadOnly(True)
self.layout1.addWidget(self.q_label1)
self.layout1.addWidget(self.q_edit1)
self.layout1.addWidget(self.q_label2)
self.layout1.addWidget(self.q_edit2)
self.layout1.addWidget(self.q_label3)
self.layout1.addWidget(self.q_combo)
self.layout1.addWidget(self.q_button_start)
self.layout1.addWidget(self.q_edit3)
self.grid_layout.setRowStretch(5,0)
self.grid_layout.setRowStretch(20,1)
self.grid_layout.setRowStretch(1,2)
self.grid_layout.setRowStretch(1,3)
self.grid_layout.setRowStretch(1,4)
self.grid_layout.setRowStretch(100,5)
self.grid_layout.setRowStretch(1,6)
self.grid_layout.addWidget(self.q_label1, 0,0)
self.grid_layout.addWidget(self.q_edit1, 1,0)
self.grid_layout.addWidget(self.q_label2, 2,0)
self.grid_layout.addWidget(self.q_edit2, 3,0)
self.grid_layout.addWidget(self.q_label3, 4,0)
self.grid_layout.addWidget(self.q_combo, 5,0)
self.grid_layout.addWidget(self.q_button_start,6,0)
self.grid_layout.addWidget(self.q_edit3,7,0) # шк-код текстом
self.content_widget = QWidget()
self.content_widget.setLayout(self.grid_layout)
self.setCentralWidget(self.content_widget)
# выпадающий список типов и кодовые соответствия
self.combo_type_items = {
"компьютер":"21",
"монитор":"22",
"сетевое об.":"23",
"токен":"24",
"принтер/МФУ":"25",
"флешка":"26",
"HID":"27",
"UPS":"28",
"другое":"29",
}
# получаем текущий каталог и переходим в него
def set_current_location(self):
path_there = os.path.dirname(os.path.realpath(__file__))
os.chdir(path_there)
# генерация штрих-кода с контрльной суммой
def gen_ean13(self,product_code: str):
# добавляем псевдослучаное значение (от времени к коду продукта)
digits_s= product_code + str(round(time.time()))
# строка продукта в список чисел
digits = [int(i) for i in digits_s]
# контрольная сумма по алгоритму ЛУна
checksum = (10 - (sum(digits[1::2]) * 3 + sum(digits[::2])) % 10) % 10
return "".join(str(i) for i in (digits + [checksum]))
# генерация картинки
def create_code_png(self,filename, code, text):
self.set_current_location()
ean13_code = EAN13(code, writer=ImageWriter())
image = ean13_code.render(
writer_options={
"module_height": 11.0,
"module_width": 0.3,
"dpi": 169,
"font_size": 0,
"text_distance": 1,
"write_text": None,
}
)
image = image.convert("1", dither=Image.Dither.NONE)
image = ImageOps.expand(image, border=17, fill=1)
draw = ImageDraw.Draw(image)
# загружаем шрифт
dst = "terminus.pil"
font = ImageFont.load(dst)
text_length = draw.textlength(text, font=font)
code_text_length = draw.textlength(code, font=font)
draw.text(((image.width - text_length) / 2, 3), text, fill="black", font=font)
draw.text(
((image.width - code_text_length) / 2, 100),
code,
fill="black",
font=font,
)
image.save(filename)
#запуск всего процесса (генерация и печать)
def start_print(self):
# берем ID по типу оборудования
type_device=self.combo_type_items[self.q_combo.currentText()]
# берем текст подписи
text_data=self.q_edit1.text()
barcode = self.gen_ean13(type_device)
# если ввели свой SN, передаем его в создание ШК
if len(self.q_edit2.text())>0:
if len(self.q_edit2.text())==12:
barcode=self.q_edit2.text()
else:
msg = QMessageBox()
msg.setWindowTitle("Внимание")
msg.setText("Должно быть 12 знаков")
msg.setIcon(QMessageBox.Warning)
msg.exec_()
exit(0)
self.q_edit3.setText(barcode)
self.create_code_png("temp.png", barcode, text_data)
self.start_process()
# запуск утилиты печати сфомированного изображения
def start_process(self):
subprocess.run(["ptouch-print", "--image", "temp.png"])
if __name__ == '__main__':
app = QApplication(sys.argv)
configparser = ChildProcessError
# таблица стилей (задаем размер шрифта)
style_sheet01 = """
* {
font-size: 11pt;
}
"""
# Применение таблицы стилей (размер шрифта) ко всему приложению
app.setStyleSheet(style_sheet01)
window = MainWindow()
# Установить размер окна
window.resize(500, 300)
# Получить допустимое разрешение
SrcSize = QtGui.QScreen.availableGeometry(QApplication.primaryScreen())
frmX = (SrcSize.width() - window.width())/2
frmY = (SrcSize.height() - window.height())/2
window.move(frmX, frmY)
window.show()
sys.exit(app.exec_())