Code_Save
Code_Save
# coding=utf-8
app = Flask(__name__)
config = {
"app_id": 2554,
"key1": "sdngKKJmqEMzvh5QQcdD2A9XBSKUNaYn",
"key2": "trMrHtvjo6myautxDUiAcYsVtaeQ8nhf",
"endpoint": "https://sb-openapi.zalopay.vn/v2/create"
}
# app_id|app_trans_id|app_user|amount|apptime|embed_data|item
data = "{}|{}|{}|{}|{}|{}|{}".format(order["app_id"],
order["app_trans_id"], order["app_user"],
order["amount"], order["app_time"],
order["embed_data"], order["item"])
try:
response = urllib.request.urlopen(url=config["endpoint"],
data=urllib.parse.urlencode(order).encode())
result = json.loads(response.read().decode('utf-8')) # Decode
response to ensure proper handling of Unicode
print(json.dumps(ordered_result, indent=4,
ensure_ascii=False)) # Log the result in terminal
with proper Unicode handling
return jsonify(ordered_result) # Return the ordered result as JSON
except Exception as e:
return jsonify({"error": str(e)}), 500
# CALLBACK
@app.route('/callback', methods=['POST'])
def callback():
result = {}
try:
cbdata = request.json
mac = hmac.new(config['key2'].encode(), cbdata['data'].encode(),
hashlib.sha256).hexdigest()
result['return_code'] = 1
result['return_message'] = 'success'
except Exception as e:
result['return_code'] = 0 # ZaloPay server sẽ callback lại (tối đa 3
lần)
result['return_message'] = str(e)
if __name__ == "__main__":
app.run(debug=True)
Test image:
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QTableWidgetItem,
QPushButton, QMessageBox, QFileDialog
from PyQt5 import uic
from PyQt5.QtCore import QDateTime, QDate, QTime
from collections import defaultdict
import matplotlib.pyplot as plt
import pandas as pd
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Revenue Graph")
self.setGeometry(100, 100, 800, 600)
self.dateEditStart.setDisplayFormat("dd-MM-yyyy")
self.dateEditStart.setDate(QDate(2023, 1, 1))
self.dateEditStart.setCalendarPopup(True)
self.dateEditStart.dateChanged.connect(self.update_table_only)
self.dateEditEnd.setDisplayFormat("dd-MM-yyyy")
self.dateEditEnd.setDate(QDate(2024, 12, 31))
self.dateEditEnd.setCalendarPopup(True)
self.dateEditEnd.dateChanged.connect(self.update_table_only)
self.tableWidget_History.setColumnCount(5)
self.tableWidget_History.setHorizontalHeaderLabels(["Name", "Phone",
"License Plate", "Time", "Money"])
self.import_button_history = self.findChild(QPushButton,
'Import_history')
self.import_button_history.clicked.connect(self.import_excel_history)
def clear_table(self):
self.tableWidget_History.setRowCount(0)
def filter_data(self):
start_date = self.dateEditStart.date()
end_date = self.dateEditEnd.date()
filtered_data = []
self.update_table_history(filtered_data)
return filtered_data
def update_table_only(self):
self.filter_data()
def update_graph(self):
self.show_revenue_graph()
def show_revenue_graph(self):
try:
# Get selected time period
selected_option = self.comboBox.currentText()
date_revenue = defaultdict(int)
start_date = self.dateEditStart.date()
end_date = self.dateEditEnd.date()
dates = sorted(date_revenue.keys())
revenues = [date_revenue[date] / 1_000_000 for date in dates] #
Convert to million VND
if not dates:
QMessageBox.warning(self, 'Thông báo', 'Không có dữ liệu để vẽ
đồ thị.', QMessageBox.Ok)
return
if selected_option == "Monthly":
x_labels = [d.toString('MM-yyyy') for d in dates] # Change x-
axis label format for "Monthly"
elif selected_option == "Yearly":
x_labels = [d.toString('yyyy') for d in dates] # Change x-
axis label format for "Yearly"
else:
x_labels = [d.toString('dd-MM-yyyy') for d in dates]
plt.bar(x_labels, revenues)
plt.xlabel('Date')
plt.ylabel('Revenue (Million VND)') # Update y-axis label
plt.title(f'Revenue Over Time ({selected_option})')
plt.xticks(rotation=45)
plt.gca().get_yaxis().get_major_formatter().set_scientific(False)
# Disable scientific notation for y-axis
self.autolabel(plt.gca().patches)
plt.tight_layout()
plt.show()
except Exception as e:
QMessageBox.critical(self, 'Lỗi', f'Đã xảy ra lỗi: {str(e)}',
QMessageBox.Ok)
def import_excel_history(self):
options = QFileDialog.Options()
fileName, _ = QFileDialog.getOpenFileName(self, "Import Excel", "",
"Excel Files (*.xlsx);;All Files (*)",
options=options)
if fileName:
try:
df = pd.read_excel(fileName)
data = df.values.tolist()
self.update_table_history(data)
print(f"Excel file imported from {fileName}") # Print the
file path
except Exception as e:
QMessageBox.critical(self, 'Error', f'Error importing file:
{str(e)}', QMessageBox.Ok)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
app = Flask(__name__)
config = {
"app_id": 2554,
"key1": "sdngKKJmqEMzvh5QQcdD2A9XBSKUNaYn",
"key2": "trMrHtvjo6myautxDUiAcYsVtaeQ8nhf",
"endpoint": "https://sb-openapi.zalopay.vn/v2/create"
}
# Configure logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(message)s')
@app.route('/get_latest_app_trans_id')
def get_latest_app_trans_id():
global latest_app_trans_id
if latest_app_trans_id:
return latest_app_trans_id
else:
return "No app_trans_id available"
@app.route("/payment", methods=["POST"])
def payment():
global latest_app_trans_id
transID = random.randrange(1000000)
amount = int(request.form['amount'])
description = request.form['description']
order = {
"app_id": config["app_id"],
"app_trans_id": "{:%y%m%d}_{}".format(datetime.today(), transID),
"app_user": "user123",
"app_time": int(round(time() * 1000)),
"embed_data": json.dumps({}),
"item": json.dumps([{}]),
"amount": amount,
"description": description,
"bank_code": "zalopayapp"
}
data = "{}|{}|{}|{}|{}|{}|{}".format(order["app_id"],
order["app_trans_id"], order["app_user"],
order["amount"], order["app_time"],
order["embed_data"], order["item"])
print(f"{order['app_trans_id']}")
send_message_to_gui(f"{order['app_trans_id']}")
latest_app_trans_id = order["app_trans_id"] # Update the
latest_app_trans_id value
try:
response = urllib.request.urlopen(url=config["endpoint"],
data=urllib.parse.urlencode(order).encode())
result = json.loads(response.read().decode('utf-8'))
# Generate QR code
qr = qrcode.QRCode(
version=1,
error_correction=qrcode.constants.ERROR_CORRECT_L,
box_size=10,
border=4,
)
qr.add_data(result.get("order_url"))
qr.make(fit=True)
ordered_result["qr_code_base64"] = img_str
print(result.get("order_url"))
send_message_to_gui(result.get("order_url"))
return jsonify(ordered_result)
except Exception as e:
return jsonify({"error": str(e)}), 500
# CALLBACK
@app.route('/callback', methods=['POST', 'GET'])
def callback():
result = {}
try:
if request.method == 'POST' or request.method == 'GET':
if request.method == 'POST':
cbdata = request.json
elif request.method == 'GET':
cbdata = request.args.to_dict()
if mac != cbdata['mac']:
result['return_code'] = -1
result['return_message'] = 'mac not equal'
else:
dataJson = json.loads(cbdata['data'])
app_trans_id = dataJson['app_trans_id']
logging.info(f"Cập nhật trạng thái đơn hàng thành công cho
app_trans_id = {app_trans_id}")
result['return_code'] = 1
result['return_message'] = 'success'
else:
result['return_code'] = -1
result['return_message'] = 'Method Not Allowed'
except Exception as e:
result['return_code'] = 0
result['return_message'] = str(e)
return jsonify(result)
try:
status_endpoint = "https://sb-openapi.zalopay.vn/v2/query"
response = urllib.request.urlopen(url=status_endpoint,
data=urllib.parse.urlencode(params).encode())
result = json.loads(response.read().decode('utf-8'))
if __name__ == "__main__":
# Khởi tạo server socket để kết nối với GUI
HOST = 'localhost' # Địa chỉ IP của máy chạy GUI.py
PORT = 12345 # Cổng mà GUI.py sẽ lắng nghe
{% block content %}
<div class="row">
<div class="col-md-6 offset-md-3">
<h2 class="mb-4">ZaloPay Payment Form</h2>
<form action="/payment" method="POST">
<div class="form-group">
<label for="amount">Amount:</label>
<input type="number" class="form-control" id="amount"
name="amount" required>
</div>
<div class="form-group">
<label for="description">Description:</label>
<textarea class="form-control" id="description"
name="description" rows="3" required></textarea>
</div>
<button type="submit" class="btn">Pay with ZaloPay</button>
</form>
<br>
<h2>Other Actions</h2>
<!-- <button class="btn" onclick="window.location.href='/callback'">Go
to Callback</button>-->
<button class="btn" onclick="window.location.href='/login'">Go to
Login</button>
<br><br>
<form onsubmit="checkOrderStatus(event)">
<div class="form-group">
<label for="app_trans_id">App Trans ID:</label>
<input type="text" class="form-control" id="app_trans_id"
name="app_trans_id" value="{{ app_trans_id }}" required>
</div>
<button type="submit" class="btn">Check Order Status</button>
<button type="button" class="btn"
onclick="updateAppTransId()">Update from Terminal</button>
</form>
</div>
</div>
<script>
function checkOrderStatus(event) {
event.preventDefault();
const appTransId = document.getElementById('app_trans_id').value;
window.location.href = `/order-status/${appTransId}`;
}
function updateAppTransId() {
fetch('/get_latest_app_trans_id')
.then(response => response.text())
.then(data => {
document.getElementById('app_trans_id').value = data;
})
.catch(error => {
console.error('Error fetching latest app_trans_id:', error);
});
}
</script>
{% endblock %}
Ready Lamp
# pip install Pillow
# pip uninstall -y setuptools
# pip install setuptools==39.1.0
# pip install setuptools==69.5.1
# pip install hydra
# shell = True
# pip install hydra-core>=1.2.0
import os
os.environ['TF_ENABLE_ONEDNN_OPTS'] = '0'
os.environ["KMP_DUPLICATE_LIB_OK"] = "TRUE"
from paddleocr import PaddleOCR, draw_ocr
from PIL import Image
from PyQt5 import uic
from PyQt5.QtMultimedia import QCameraInfo
from PyQt5.QtWidgets import QApplication, QMainWindow, QLabel,
QTableWidgetItem, QPushButton, QLineEdit, QMessageBox, \
QFileDialog, QInputDialog
from PyQt5.QtCore import QThread, pyqtSignal, pyqtSlot, QTimer, QDateTime, Qt,
QDate, QTime
from PyQt5.QtGui import QImage, QPixmap
import cv2, time, sysinfo
import numpy as np
import random as rnd
import random
import sys
from ultralytics import YOLO
import pandas as pd
import openpyxl
import matplotlib
matplotlib.use('Qt5Agg')
import matplotlib.pyplot as plt
from collections import defaultdict
class ThreadClass(QThread):
ImageUpdate = pyqtSignal(np.ndarray) # Tạo tín hiệu để cập nhật hình ảnh
FPS = pyqtSignal(int) # Tạo tín hiệu để cập nhật số khung hình trên giây
(FPS)
global camIndex # Đặt biến camIndex là biến toàn cục
def run(self):
if self.fileName:
Capture = cv2.VideoCapture(self.fileName)
elif camIndex == 0:
Capture = cv2.VideoCapture(camIndex) # Mở camera với chỉ số
camIndex
elif camIndex == 1:
Capture = cv2.VideoCapture(camIndex, cv2.CAP_DSHOW) # Mở camera
với chỉ số camIndex sử dụng DirectShow
def stop(self):
self.ThreadActive = False # Dừng luồng
self.quit() # Thoát luồng
class boardInfoClass(QThread):
cpu = pyqtSignal(float) # Tạo tín hiệu để cập nhật sử dụng CPU
ram = pyqtSignal(tuple) # Tạo tín hiệu để cập nhật sử dụng RAM
def run(self):
self.ThreadActive = True # Đặt cờ hiệu hoạt động của luồng
while self.ThreadActive:
cpu = sysinfo.getCPU() # Lấy thông tin sử dụng CPU
ram = sysinfo.getRAM() # Lấy thông tin sử dụng RAM
# temp = sysinfo.getTemp() # Lấy thông tin nhiệt độ (bị comment
do không dùng)
self.cpu.emit(cpu) # Phát tín hiệu cập nhật CPU
self.ram.emit(ram) # Phát tín hiệu cập nhật RAM
def stop(self):
self.ThreadActive = False # Dừng luồng
self.quit() # Thoát luồng
class randomColorClass(QThread):
color = pyqtSignal(tuple) # Tạo tín hiệu để cập nhật màu ngẫu nhiên
def run(self):
self.ThreadActive = True # Đặt cờ hiệu hoạt động của luồng
while self.ThreadActive:
color = ([rnd.randint(0, 256), rnd.randint(0, 256), rnd.randint(0,
256)],
[rnd.randint(0, 256), rnd.randint(0, 256), rnd.randint(0,
256)],
[rnd.randint(0, 256), rnd.randint(0, 256), rnd.randint(0,
256)]
) # Tạo ba màu ngẫu nhiên
self.color.emit(color) # Phát tín hiệu cập nhật màu
time.sleep(2) # Chờ 2 giây trước khi tạo màu mới
def stop(self):
self.ThreadActive = False # Dừng luồng
self.quit() # Thoát luồng
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.ui = uic.loadUi("Opencv_PiDash.ui", self) # Tải giao diện từ tệp
Opencv_PiDash.ui
self.btn_close.clicked.connect(
self.Close_software) # Kết nối tín hiệu clicked của nút đóng với
hàm Close_software
self.comboBox.currentIndexChanged.connect(self.update_graph)
self.initUI()
# self.generate_random_data()
def clock(self):
self.DateTime = QDateTime.currentDateTime() # Lấy thời gian hiện tại
self.lcd_clock.display(
self.DateTime.toString('hh:mm:ss dd-MM-yyyy')) # Hiển thị thời
gian hiện tại trên đồng hồ LCD
def initUI(self):
self.TableList()
# Kết nối nút Set với phương thức cập nhật thời gian trong bảng
self.setButton = self.findChild(QPushButton, 'setButton')
self.setButton.clicked.connect(self.update_time_in_table)
self.clear_selected_button = self.findChild(QPushButton,
'clearSelectedButton')
self.clear_selected_button.clicked.connect(self.clear_selected_row)
self.export_button_history = self.findChild(QPushButton,
'Export_history')
self.export_button_history.clicked.connect(self.export_excel_history)
self.import_button_history = self.findChild(QPushButton,
'Import_history')
self.import_button_history.clicked.connect(self.import_excel_history)
def TableList(self):
# Đặt tên cho các cột
headers = ["Name", "Phone", "License Plate", "Time"]
self.tableWidget.setColumnCount(len(headers))
self.tableWidget.setHorizontalHeaderLabels(headers)
self.update_table(data)
item = QTableWidgetItem(value)
self.tableWidget.setItem(rowPosition, column, item)
# Tự động điều chỉnh kích thước của các cột và hàng dựa trên nội dung
self.tableWidget.resizeColumnsToContents()
self.tableWidget.resizeRowsToContents()
# Tự động điều chỉnh kích thước của các cột và hàng dựa trên nội dung
self.tableWidget_History.resizeColumnsToContents()
self.tableWidget_History.resizeRowsToContents()
found = False
money = "0 VND"
# Kiểm tra xem license_plate đã tồn tại trong cột "License Plate" hay
chưa
for row in range(self.tableWidget.rowCount()):
item = self.tableWidget.item(row, 2) # Cột "License Plate" là cột
thứ 3 (chỉ mục 2)
if item.text() == plate_num:
QMessageBox.warning(self, 'Thông báo',
'Biển số xe đã tồn tại trong danh sách
đăng ký. Bạn không cần phải trả tiền.',
QMessageBox.Ok)
# Lưu lại lịch sử giao dịch
name = self.tableWidget.item(row, 0).text()
phone = self.tableWidget.item(row, 1).text()
license_plate = self.tableWidget.item(row, 2).text()
self.update_transaction_history(name, phone, license_plate,
currentTime, money)
found = True
break # Dừng lại nếu tìm thấy biển số xe trùng
if not found:
reply = QMessageBox.question(self, 'Thông báo',
'Biển số xe chưa được đăng ký.\nBạn
có muốn đăng ký vé tháng chứ?',
QMessageBox.Yes | QMessageBox.No)
if reply == QMessageBox.Yes:
# Hiển thị các hộp nhập liệu để người dùng điền thông tin
name, ok1 = QInputDialog.getText(self, 'Đăng ký vé tháng',
'Nhập tên:')
phone, ok2 = QInputDialog.getText(self, 'Đăng ký vé tháng',
'Nhập số điện thoại:')
license_plate, ok3 = QInputDialog.getText(self, 'Đăng ký vé
tháng', 'Nhập biển số xe:', text=plate_num)
# Tự động điều chỉnh kích thước của các cột và hàng dựa
trên nội dung
self.tableWidget.resizeColumnsToContents()
self.tableWidget.resizeRowsToContents()
def clear_table(self):
self.tableWidget_History.setRowCount(0)
def filter_data(self):
start_date = self.dateEditStart.date()
end_date = self.dateEditEnd.date()
filtered_data = []
self.update_table_history(filtered_data)
return filtered_data
def update_table_only(self):
self.filter_data()
def update_graph(self):
self.show_revenue_graph()
def show_revenue_graph(self):
try:
# Get selected time period
selected_option = self.comboBox.currentText()
date_revenue = defaultdict(int)
start_date = self.dateEditStart.date()
end_date = self.dateEditEnd.date()
# Calculate revenue based on selected time period
for row in range(self.tableWidget_History.rowCount()):
money_str = self.tableWidget_History.item(row,
4).text().replace(" VND", "")
money = int(money_str)
date_str = self.tableWidget_History.item(row, 3).text()
date = QDateTime.fromString(date_str, 'hh:mm:ss dd-MM-
yyyy').date()
dates = sorted(date_revenue.keys())
revenues = [date_revenue[date] / 1_000_000 for date in dates] #
Convert to million VND
if not dates:
QMessageBox.warning(self, 'Thông báo', 'Không có dữ liệu để vẽ
đồ thị.', QMessageBox.Ok)
return
if selected_option == "Monthly":
x_labels = [d.toString('MM-yyyy') for d in dates] # Change x-
axis label format for "Monthly"
elif selected_option == "Yearly":
x_labels = [d.toString('yyyy') for d in dates] # Change x-
axis label format for "Yearly"
else:
x_labels = [d.toString('dd-MM-yyyy') for d in dates]
plt.bar(x_labels, revenues)
plt.xlabel('Date')
plt.ylabel('Revenue (Million VND)') # Update y-axis label
plt.title(f'Revenue Over Time ({selected_option})')
plt.xticks(rotation=45)
plt.gca().get_yaxis().get_major_formatter().set_scientific(False)
# Disable scientific notation for y-axis
self.autolabel(plt.gca().patches)
plt.tight_layout()
plt.show()
except Exception as e:
QMessageBox.critical(self, 'Lỗi', f'Đã xảy ra lỗi: {str(e)}',
QMessageBox.Ok)
def generate_random_data(self):
data_history = []
start_date = QDateTime(QDate(2023, 1, 1), QTime(0, 0))
end_date = QDateTime(QDate(2024, 12, 31), QTime(23, 59))
current_date = start_date
while current_date <= end_date:
name = f"Person-{random.randint(1, 100)}"
phone = f"{random.randint(100000000, 999999999)}"
license_plate = f"{random.choice(['H', '51A', '60A'])}-
{random.uniform(100.00, 999.99):.2f}"
time_str = current_date.toString('hh:mm:ss dd-MM-yyyy')
money = random.randint(10000, 1000000)
current_date = current_date.addDays(1)
self.update_table_history(data_history)
print("Random data generated successfully.")
def export_excel(self):
options = QFileDialog.Options()
fileName, _ = QFileDialog.getSaveFileName(self, "Export Excel", "",
"Excel Files (*.xlsx);;All Files (*)",
options=options)
if fileName:
try:
data = []
for row in range(self.tableWidget.rowCount()):
rowData = []
for column in range(self.tableWidget.columnCount()):
item = self.tableWidget.item(row, column)
if item is not None:
rowData.append(item.text())
else:
rowData.append('')
data.append(rowData)
def export_excel_history(self):
options = QFileDialog.Options()
fileName, _ = QFileDialog.getSaveFileName(self, "Export Excel", "",
"Excel Files (*.xlsx);;All Files (*)",
options=options)
if fileName:
try:
data = []
for row in range(self.tableWidget_History.rowCount()):
rowData = []
for column in
range(self.tableWidget_History.columnCount()):
item = self.tableWidget_History.item(row, column)
if item is not None:
rowData.append(item.text())
else:
rowData.append('')
data.append(rowData)
def import_excel(self):
options = QFileDialog.Options()
fileName, _ = QFileDialog.getOpenFileName(self, "Import Excel", "",
"Excel Files (*.xlsx);;All Files (*)",
options=options)
if fileName:
try:
df = pd.read_excel(fileName)
data = df.values.tolist()
self.update_table(data)
print(f"Excel file imported from {fileName}") # Print the
file path
except Exception as e:
print(f"Error importing file: {e}")
def import_excel_history(self):
options = QFileDialog.Options()
fileName, _ = QFileDialog.getOpenFileName(self, "Import Excel", "",
"Excel Files (*.xlsx);;All Files (*)",
options=options)
if fileName:
try:
df = pd.read_excel(fileName)
data = df.values.tolist()
self.update_table_history(data)
print(f"Excel file imported from {fileName}") # Print the
file path
except Exception as e:
QMessageBox.critical(self, 'Error', f'Error importing file:
{str(e)}', QMessageBox.Ok)
def clear_all_rows(self):
self.tableWidget.setRowCount(0)
def clear_selected_row(self):
current_row = self.tableWidget.currentRow()
if current_row != -1:
self.tableWidget.removeRow(current_row)
else:
QMessageBox.warning(self, 'Warning', 'No row selected to delete.',
QMessageBox.Ok)
def open_file_dialog(self):
options = QFileDialog.Options()
fileName, _ = QFileDialog.getOpenFileName(self, "Open File", "",
"Images and Videos (*.png
*.jpg *.bmp *.mp4 *.avi);;All Files (*)",
options=options)
if fileName:
if fileName.lower().endswith(('.png', '.jpg', '.bmp')):
self.display_image(fileName)
print(f"Selected file: {fileName}") # In ra địa chỉ file trên
terminal
if self.btn_setObject1.isChecked():
self.GetObject_one(fileName) # Gọi phương thức
GetObject_one với fileName được chọn
elif fileName.lower().endswith(('.mp4', '.avi')):
self.display_video(fileName)
self.disp_main.setPixmap(QPixmap.fromImage(qImg).scaled(self.disp_main.size(),
Qt.KeepAspectRatio))
def take_snapshot(self):
# Grab the content of disp_main
pixmap = self.disp_main.pixmap()
if pixmap:
# Convert QPixmap to QImage
qimage = pixmap.toImage()
@pyqtSlot(np.ndarray)
def opencv_emit(self, Image):
"""
Trong quá trình chuyển đổi hình ảnh để hiển thị trên Qlabel, cần phải
chuyển đổi từ np.array sang QPixmap.
Hình ảnh nhận được là Numpy array, khi dùng hàm original =
cvt_cv_qt(Image), biến original sẽ có kiểu QtGui.QPixmap.
"""
#
------------------------------------------------------------------------------
----------------------
global camIndex
camIndex = self.camlist.currentIndex() # Lấy chỉ số của camera
hiện tại
# Opencv QThread
self.Worker1_Opencv = ThreadClass() # Tạo đối tượng ThreadClass
để xử lý video
self.Worker1_Opencv.ImageUpdate.connect(
self.opencv_emit) # Kết nối tín hiệu ImageUpdate với phương
thức opencv_emit
self.Worker1_Opencv.FPS.connect(self.get_FPS) # Kết nối tín hiệu
FPS với phương thức get_FPS
self.Worker1_Opencv.start() # Bắt đầu luồng
def set_object1(self):
if self.btn_setObject1.isChecked():
print("Object Detect is checked.")
self.run_lamp_on.start()
else:
print("Object Detect is unchecked.")
self.run_lamp_on.stop()
result = result[0]
image = Image.open(img_path).convert('RGB')
boxes = [line[0] for line in result]
txts = [line[1][0] for line in result]
scores = [line[1][1] for line in result]
im_show = draw_ocr(image, boxes, txts, scores,
font_path='./latin.ttf')
im_show = Image.fromarray(im_show)
im_show.save('result.jpg')
Image_Obj_1 = './cropped_image.jpg'
original = QImage(Image_Obj_1) # Chuyển đổi hình ảnh từ định dạng
numpy array sang QPixmap
self.disp_obj1.setPixmap(QPixmap(original)) # Hiển thị hình ảnh
ban đầu trên nhãn chính
self.disp_obj1.setScaledContents(True) # Cho phép thay đổi kích
thước nội dung của nhãn
Image_Obj_2 = './corrected_image.jpg'
self.disp_obj2.setPixmap(QPixmap(QImage(Image_Obj_2))) # Hiển thị
hình ảnh ban đầu trên nhãn chính
self.disp_obj2.setScaledContents(True) # Cho phép thay đổi kích
thước nội dung của nhãn
self.License_plate.setText(plate_num)
# Kiểm tra và cập nhật bảng
self.update_time_in_table(plate_num)
except Exception as error:
pass # Bỏ qua mọi lỗi xảy ra
def Close_software(self):
self.Worker1_Opencv.stop() # Dừng luồng xử lý video
self.resource_usage.stop() # Dừng đo lường tài nguyên
sys.exit(app.exec_()) # Thoát ứng dụng
def Motor_on(self):
if self.btn_motor.isChecked():
self.textEdit.append(
f"{self.DateTime.toString('d MMMM yy hh:mm:ss')}: Motor ON")
# Thêm văn bản vào textEdit khi motor bật
self.btn_motor.setText('Motor OFF') # Thay đổi nhãn của nút motor
thành 'Motor OFF'
# self.motor_on = QTimer(self, interval=1000)
# self.motor_on.timeout.connect(self.Motor_state)
self.motor_on.start() # Bắt đầu motor
else:
self.textEdit.append(
f"{self.DateTime.toString('d MMMM yy hh:mm:ss')}: Motor OFF")
# Thêm văn bản vào textEdit khi motor tắt
self.motor_on.stop() # Dừng motor
self.btn_motor.setText('Motor ON') # Thay đổi nhãn của nút motor
thành 'Motor ON'
def Ready_Light(self):
if self.Status_lamp[0]:
self.QLabel_Ready_Light.setStyleSheet(
"background-color: rgb(85, 255, 0); border-radius:35px") #
Đặt màu nền của đèn xanh là màu xanh lá
else:
self.QLabel_Ready_Light.setStyleSheet(
"background-color: rgb(184, 230, 191); border-radius:35px") #
Đặt màu nền của đèn xanh là màu xanh nhạt
def Run_Light(self):
if self.Status_lamp[1]:
self.Qlabel_yellowlight.setStyleSheet(
"background-color: rgb(255, 195, 0); border-radius:35px") #
Đặt màu nền của đèn vàng là màu vàng đậm
else:
self.Qlabel_yellowlight.setStyleSheet(
"background-color: rgb(242, 214, 117); border-radius:35px") #
Đặt màu nền của đèn vàng là màu vàng nhạt
self.Status_lamp[1] = not self.Status_lamp[1] # Đảo ngược trạng thái
của đèn vàng
# IO.output(IO_OUTPUT[1], self.Status_lamp[1])
if __name__ == "__main__":
app = QApplication([])
window = MainWindow()
window.show()
app.exec_()
import os
os.environ['TF_ENABLE_ONEDNN_OPTS'] = '0'
os.environ["KMP_DUPLICATE_LIB_OK"] = "TRUE"
from paddleocr import PaddleOCR, draw_ocr
from PIL import Image
from PyQt5 import uic
from PyQt5.QtMultimedia import QCameraInfo
from PyQt5.QtWidgets import QApplication, QMainWindow, QLabel,
QTableWidgetItem, QPushButton, QLineEdit, QMessageBox, \
QFileDialog, QInputDialog, QDialog, QWidget, QVBoxLayout, QTextEdit
from PyQt5.QtCore import QThread, pyqtSignal, pyqtSlot, QTimer, QDateTime, Qt,
QDate, QTime
from PyQt5.QtGui import QImage, QPixmap
import cv2, time, sysinfo
import numpy as np
import random as rnd
import random
import sys
from ultralytics import YOLO
import pandas as pd
import openpyxl
import matplotlib
matplotlib.use('Qt5Agg')
import matplotlib.pyplot as plt
from collections import defaultdict
import socket
class ThreadClass(QThread):
ImageUpdate = pyqtSignal(np.ndarray) # Tạo tín hiệu để cập nhật hình ảnh
FPS = pyqtSignal(int) # Tạo tín hiệu để cập nhật số khung hình trên giây (FPS)
global camIndex # Đặt biến camIndex là biến toàn cục
def run(self):
if self.fileName:
Capture = cv2.VideoCapture(self.fileName)
elif camIndex == 0:
Capture = cv2.VideoCapture(camIndex) # Mở camera với chỉ số camIndex
elif camIndex == 1:
Capture = cv2.VideoCapture(camIndex, cv2.CAP_DSHOW) # Mở camera với
chỉ số camIndex sử dụng DirectShow
def stop(self):
self.ThreadActive = False # Dừng luồng
self.quit() # Thoát luồng
class boardInfoClass(QThread):
cpu = pyqtSignal(float) # Tạo tín hiệu để cập nhật sử dụng CPU
ram = pyqtSignal(tuple) # Tạo tín hiệu để cập nhật sử dụng RAM
def run(self):
self.ThreadActive = True # Đặt cờ hiệu hoạt động của luồng
while self.ThreadActive:
cpu = sysinfo.getCPU() # Lấy thông tin sử dụng CPU
ram = sysinfo.getRAM() # Lấy thông tin sử dụng RAM
# temp = sysinfo.getTemp() # Lấy thông tin nhiệt độ (bị comment do không
dùng)
self.cpu.emit(cpu) # Phát tín hiệu cập nhật CPU
self.ram.emit(ram) # Phát tín hiệu cập nhật RAM
def stop(self):
self.ThreadActive = False # Dừng luồng
self.quit() # Thoát luồng
class SocketThread(QThread):
data_signal = pyqtSignal(str)
def __init__(self):
super().__init__()
self.host = '0.0.0.0'
self.port = 9000
self._run_flag = True
def stop(self):
self._run_flag = False
def run(self):
try:
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((self.host, self.port))
s.listen()
s.settimeout(1) # Set a timeout for accept()
print(f"Listening on {self.host}:{self.port}")
while self._run_flag:
try:
conn, addr = s.accept()
with conn:
print(f"Connected by {addr}")
while self._run_flag:
data = conn.recv(1024)
if not data:
break
messages = data.decode().strip().split('\n')
for message in messages:
self.data_signal.emit(message)
except socket.timeout:
continue
except Exception as e:
print(f"Error in SocketThread: {e}")
class RFIDReader(QDialog):
def __init__(self):
super().__init__()
self.initUI()
self.initSocket()
self.DateTime = QDateTime.currentDateTime()
self.motor_on = QTimer(self, interval=1000) # Timer for motor state, example
usage
def initUI(self):
self.setWindowTitle('RFID Reader and Motor Control')
self.setGeometry(100, 100, 400, 300)
layout = QVBoxLayout()
layout.addWidget(self.uidLabel)
layout.addWidget(self.statusLabel)
layout.addWidget(self.textEdit)
layout.addWidget(self.btn_motor)
self.setLayout(layout)
def initSocket(self):
self.thread = SocketThread()
self.thread.data_signal.connect(self.updateUI)
self.thread.start()
def toggle_motor(self):
if self.btn_motor.isChecked():
self.textEdit.append(
f"{self.DateTime.toString('d MMMM yy hh:mm:ss')}: Motor ON")
self.btn_motor.setText('Motor OFF')
self.sendCommand("SERVO:ON")
else:
self.textEdit.append(
f"{self.DateTime.toString('d MMMM yy hh:mm:ss')}: Motor OFF")
self.btn_motor.setText('Motor ON')
self.sendCommand("SERVO:OFF")
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.ui = uic.loadUi("Opencv_PiDash.ui", self) # Tải giao diện từ tệp
Opencv_PiDash.ui
self.btn_close.clicked.connect(
self.Close_software) # Kết nối tín hiệu clicked của nút đóng với hàm
Close_software
self.comboBox.currentIndexChanged.connect(self.update_graph)
self.btn_call.clicked.connect(self.showRFIDReader)
self.initUI()
def showRFIDReader(self):
self.rfid_reader = RFIDReader()
self.rfid_reader.exec_()
def clock(self):
self.DateTime = QDateTime.currentDateTime() # Lấy thời gian hiện tại
self.lcd_clock.display(
self.DateTime.toString('hh:mm:ss dd-MM-yyyy')) # Hiển thị thời gian hiện tại
trên đồng hồ LCD
def initUI(self):
self.TableList()
# Kết nối nút Set với phương thức cập nhật thời gian trong bảng
self.setButton = self.findChild(QPushButton, 'setButton')
self.setButton.clicked.connect(self.update_time_in_table)
def TableList(self):
# Đặt tên cho các cột
headers = ["Name", "Phone", "License Plate", "Time"]
self.tableWidget.setColumnCount(len(headers))
self.tableWidget.setHorizontalHeaderLabels(headers)
self.update_table(data)
item = QTableWidgetItem(value)
self.tableWidget.setItem(rowPosition, column, item)
# Tự động điều chỉnh kích thước của các cột và hàng dựa trên nội dung
self.tableWidget.resizeColumnsToContents()
self.tableWidget.resizeRowsToContents()
# Tự động điều chỉnh kích thước của các cột và hàng dựa trên nội dung
self.tableWidget_History.resizeColumnsToContents()
self.tableWidget_History.resizeRowsToContents()
found = False
money = "0 VND"
# Kiểm tra xem license_plate đã tồn tại trong cột "License Plate" hay chưa
for row in range(self.tableWidget.rowCount()):
item = self.tableWidget.item(row, 2) # Cột "License Plate" là cột thứ 3 (chỉ
mục 2)
if item.text() == plate_num:
QMessageBox.warning(self, 'Thông báo',
'Biển số xe đã tồn tại trong danh sách đăng ký. Bạn không
cần phải trả tiền.',
QMessageBox.Ok)
# Lưu lại lịch sử giao dịch
name = self.tableWidget.item(row, 0).text()
phone = self.tableWidget.item(row, 1).text()
license_plate = self.tableWidget.item(row, 2).text()
self.update_transaction_history(name, phone, license_plate, currentTime,
money)
found = True
break # Dừng lại nếu tìm thấy biển số xe trùng
if not found:
reply = QMessageBox.question(self, 'Thông báo',
'Biển số xe chưa được đăng ký.\nBạn có muốn đăng ký vé
tháng chứ?',
QMessageBox.Yes | QMessageBox.No)
if reply == QMessageBox.Yes:
# Hiển thị các hộp nhập liệu để người dùng điền thông tin
name, ok1 = QInputDialog.getText(self, 'Đăng ký vé tháng', 'Nhập tên:')
phone, ok2 = QInputDialog.getText(self, 'Đăng ký vé tháng', 'Nhập số điện
thoại:')
license_plate, ok3 = QInputDialog.getText(self, 'Đăng ký vé tháng', 'Nhập
biển số xe:', text=plate_num)
# Tự động điều chỉnh kích thước của các cột và hàng dựa trên nội dung
self.tableWidget.resizeColumnsToContents()
self.tableWidget.resizeRowsToContents()
# Tự động điều chỉnh kích thước của các cột và hàng dựa trên nội dung
self.tableWidget_History.resizeColumnsToContents()
self.tableWidget_History.resizeRowsToContents()
def clear_table(self):
self.tableWidget_History.setRowCount(0)
def filter_data(self):
start_date = self.dateEditStart.date()
end_date = self.dateEditEnd.date()
filtered_data = []
self.update_table_history(filtered_data)
return filtered_data
def update_table_only(self):
self.filter_data()
def update_graph(self):
self.show_revenue_graph()
def show_revenue_graph(self):
try:
# Get selected time period
selected_option = self.comboBox.currentText()
date_revenue = defaultdict(int)
start_date = self.dateEditStart.date()
end_date = self.dateEditEnd.date()
dates = sorted(date_revenue.keys())
revenues = [date_revenue[date] / 1_000_000 for date in dates] # Convert
to million VND
if not dates:
QMessageBox.warning(self, 'Thông báo', 'Không có dữ liệu để vẽ đồ thị.',
QMessageBox.Ok)
return
if selected_option == "Monthly":
x_labels = [d.toString('MM-yyyy') for d in dates] # Change x-axis label
format for "Monthly"
elif selected_option == "Yearly":
x_labels = [d.toString('yyyy') for d in dates] # Change x-axis label format
for "Yearly"
else:
x_labels = [d.toString('dd-MM-yyyy') for d in dates]
plt.bar(x_labels, revenues)
plt.xlabel('Date')
plt.ylabel('Revenue (Million VND)') # Update y-axis label
plt.title(f'Revenue Over Time ({selected_option})')
plt.xticks(rotation=45)
plt.gca().get_yaxis().get_major_formatter().set_scientific(False) # Disable
scientific notation for y-axis
self.autolabel(plt.gca().patches)
plt.tight_layout()
plt.show()
except Exception as e:
QMessageBox.critical(self, 'Lỗi', f'Đã xảy ra lỗi: {str(e)}', QMessageBox.Ok)
def export_excel(self):
options = QFileDialog.Options()
fileName, _ = QFileDialog.getSaveFileName(self, "Export Excel", "", "Excel Files
(*.xlsx);;All Files (*)",
options=options)
if fileName:
try:
data = []
for row in range(self.tableWidget.rowCount()):
rowData = []
for column in range(self.tableWidget.columnCount()):
item = self.tableWidget.item(row, column)
if item is not None:
rowData.append(item.text())
else:
rowData.append('')
data.append(rowData)
def export_excel_history(self):
options = QFileDialog.Options()
fileName, _ = QFileDialog.getSaveFileName(self, "Export Excel", "", "Excel Files
(*.xlsx);;All Files (*)",
options=options)
if fileName:
try:
data = []
for row in range(self.tableWidget_History.rowCount()):
rowData = []
for column in range(self.tableWidget_History.columnCount()):
item = self.tableWidget_History.item(row, column)
if item is not None:
rowData.append(item.text())
else:
rowData.append('')
data.append(rowData)
def import_excel(self):
options = QFileDialog.Options()
fileName, _ = QFileDialog.getOpenFileName(self, "Import Excel", "", "Excel Files
(*.xlsx);;All Files (*)",
options=options)
if fileName:
try:
df = pd.read_excel(fileName)
data = df.values.tolist()
self.update_table(data)
print(f"Excel file imported from {fileName}") # Print the file path
except Exception as e:
print(f"Error importing file: {e}")
def import_excel_history(self):
options = QFileDialog.Options()
fileName, _ = QFileDialog.getOpenFileName(self, "Import Excel", "", "Excel Files
(*.xlsx);;All Files (*)",
options=options)
if fileName:
try:
df = pd.read_excel(fileName)
data = df.values.tolist()
self.update_table_history(data)
print(f"Excel file imported from {fileName}") # Print the file path
except Exception as e:
QMessageBox.critical(self, 'Error', f'Error importing file: {str(e)}',
QMessageBox.Ok)
def clear_all_rows(self):
self.tableWidget.setRowCount(0)
def clear_selected_row(self):
current_row = self.tableWidget.currentRow()
if current_row != -1:
self.tableWidget.removeRow(current_row)
else:
QMessageBox.warning(self, 'Warning', 'No row selected to delete.',
QMessageBox.Ok)
def open_file_dialog(self):
options = QFileDialog.Options()
fileName, _ = QFileDialog.getOpenFileName(self, "Open File", "",
"Images and Videos (*.png *.jpg *.bmp *.mp4
*.avi);;All Files (*)",
options=options)
if fileName:
if fileName.lower().endswith(('.png', '.jpg', '.bmp')):
self.display_image(fileName)
print(f"Selected file: {fileName}") # In ra địa chỉ file trên terminal
if self.btn_setObject1.isChecked():
self.GetObject_one(fileName) # Gọi phương thức GetObject_one với
fileName được chọn
elif fileName.lower().endswith(('.mp4', '.avi')):
self.display_video(fileName)
def take_snapshot(self):
# Grab the content of disp_main
pixmap = self.disp_main.pixmap()
if pixmap:
# Convert QPixmap to QImage
qimage = pixmap.toImage()
@pyqtSlot(np.ndarray)
def opencv_emit(self, Image):
"""
Trong quá trình chuyển đổi hình ảnh để hiển thị trên Qlabel, cần phải chuyển
đổi từ np.array sang QPixmap.
Hình ảnh nhận được là Numpy array, khi dùng hàm original =
cvt_cv_qt(Image), biến original sẽ có kiểu QtGui.QPixmap.
"""
h, w, ch = rgb_img.shape # Lấy chiều cao, chiều rộng và số kênh của hình ảnh
bytes_per_line = ch * w # Tính số byte trên mỗi dòng
cvt2QtFormat = QImage(rgb_img.data, w, h, bytes_per_line,
QImage.Format_RGB888) # Chuyển đổi hình ảnh sang định dạng
QImage
pixmap = QPixmap.fromImage(cvt2QtFormat) # Chuyển đổi QImage sang
QPixmap
# ----------------------------------------------------------------------------------------------------
global camIndex
camIndex = self.camlist.currentIndex() # Lấy chỉ số của camera hiện tại
# Opencv QThread
self.Worker1_Opencv = ThreadClass() # Tạo đối tượng ThreadClass để xử lý
video
self.Worker1_Opencv.ImageUpdate.connect(
self.opencv_emit) # Kết nối tín hiệu ImageUpdate với phương thức
opencv_emit
self.Worker1_Opencv.start() # Bắt đầu luồng
def set_object1(self):
if self.btn_setObject1.isChecked():
print("Object Detect is checked.")
self.run_lamp_on.start()
else:
print("Object Detect is unchecked.")
self.run_lamp_on.stop()
result = result[0]
image = Image.open(img_path).convert('RGB')
boxes = [line[0] for line in result]
txts = [line[1][0] for line in result]
scores = [line[1][1] for line in result]
im_show = draw_ocr(image, boxes, txts, scores, font_path='./latin.ttf')
im_show = Image.fromarray(im_show)
im_show.save('result.jpg')
Image_Obj_1 = './cropped_image.jpg'
original = QImage(Image_Obj_1) # Chuyển đổi hình ảnh từ định dạng
numpy array sang QPixmap
self.disp_obj1.setPixmap(QPixmap(original)) # Hiển thị hình ảnh ban đầu
trên nhãn chính
self.disp_obj1.setScaledContents(True) # Cho phép thay đổi kích thước nội
dung của nhãn
Image_Obj_2 = './corrected_image.jpg'
self.disp_obj2.setPixmap(QPixmap(QImage(Image_Obj_2))) # Hiển thị hình
ảnh ban đầu trên nhãn chính
self.disp_obj2.setScaledContents(True) # Cho phép thay đổi kích thước nội
dung của nhãn
self.License_plate.setText(plate_num)
def Close_software(self):
self.Worker1_Opencv.stop() # Dừng luồng xử lý video
self.resource_usage.stop() # Dừng đo lường tài nguyên
sys.exit(app.exec_()) # Thoát ứng dụng
def Run_Light(self):
if self.Status_lamp[1]:
self.Qlabel_yellowlight.setStyleSheet(
"background-color: rgb(255, 195, 0); border-radius:35px") # Đặt màu nền
của đèn vàng là màu vàng đậm
else:
self.Qlabel_yellowlight.setStyleSheet(
"background-color: rgb(242, 214, 117); border-radius:35px") # Đặt màu
nền của đèn vàng là màu vàng nhạt
self.Status_lamp[1] = not self.Status_lamp[1] # Đảo ngược trạng thái của đèn
vàng
# IO.output(IO_OUTPUT[1], self.Status_lamp[1])
if __name__ == "__main__":
app = QApplication([])
window = MainWindow()
window.show()
app.exec_()
import sys
import socket
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QLabel,
QTextEdit, QVBoxLayout, QWidget, QDialog
from PyQt5.QtCore import QThread, pyqtSignal, QDateTime, QTimer
class SocketThread(QThread):
data_signal = pyqtSignal(str)
def __init__(self):
super().__init__()
self.host = '0.0.0.0'
self.port = 9000
self._run_flag = True
def stop(self):
self._run_flag = False
def run(self):
try:
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((self.host, self.port))
s.listen()
s.settimeout(1) # Set a timeout for accept()
print(f"Listening on {self.host}:{self.port}")
while self._run_flag:
try:
conn, addr = s.accept()
with conn:
print(f"Connected by {addr}")
while self._run_flag:
data = conn.recv(1024)
if not data:
break
messages = data.decode().strip().split('\n')
for message in messages:
self.data_signal.emit(message)
except socket.timeout:
continue
except Exception as e:
print(f"Error in SocketThread: {e}")
class RFIDReader(QDialog):
def __init__(self):
super().__init__()
self.initUI()
self.initSocket()
self.DateTime = QDateTime.currentDateTime()
self.motor_on = QTimer(self, interval=1000) # Timer for motor state, example
usage
def initUI(self):
self.setWindowTitle('RFID Reader and Motor Control')
self.setGeometry(100, 100, 400, 300)
layout = QVBoxLayout()
layout.addWidget(self.uidLabel)
layout.addWidget(self.statusLabel)
layout.addWidget(self.textEdit)
layout.addWidget(self.btn_motor)
self.setLayout(layout)
def initSocket(self):
self.thread = SocketThread()
self.thread.data_signal.connect(self.updateUI)
self.thread.start()
def toggle_motor(self):
if self.btn_motor.isChecked():
self.textEdit.append(
f"{self.DateTime.toString('d MMMM yy hh:mm:ss')}: Motor ON")
self.btn_motor.setText('Motor OFF')
self.sendCommand("SERVO:ON")
else:
self.textEdit.append(
f"{self.DateTime.toString('d MMMM yy hh:mm:ss')}: Motor OFF")
self.btn_motor.setText('Motor ON')
self.sendCommand("SERVO:OFF")
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.setWindowTitle('Main Window')
self.setGeometry(100, 100, 300, 200)
layout = QVBoxLayout()
layout.addWidget(self.btn_call)
container = QWidget()
container.setLayout(layout)
self.setCentralWidget(container)
def showRFIDReader(self):
self.rfid_reader = RFIDReader()
self.rfid_reader.exec_()
if __name__ == '__main__':
app = QApplication(sys.argv)
main_win = MainWindow()
main_win.show()
sys.exit(app.exec_())