C# İle İlgili Bir konuda Datagridview nesnesiyle alakalı bir kod parçacığı istenmişti, bende bunu biraz daha geliştirerek daha farklı özellikler ekleterek Python koduna dönüştürdüm.
PROGRAM PARÇACIĞIN ALAKALI VİDEOSUNU İZLEMEK İSTERSENİZ
Python Kullanıcı Dostu Dosya Yönetim Uygulaması Kodlama
Kullanıcı Dostu Dosya Yönetim Uygulaması
Bu Python kodu, kullanıcının bilgisayarındaki dosyaları rahat ve etkili bir şekilde yönetebilmesini sağlayan grafik arayüzlü bir uygulamadır. PyQt5 kütüphanesi kullanılarak geliştirilen bu uygulama, sürükle-bırak ile dosya ekleme, listeleme ve çeşitli formatlarda dışarı aktarma gibi temel işlevleri yerine getirir.
Uygulamanın Temel Özellikleri
- Dosya Listeleme ve Bilgileri Gösterme
Uygulama, eklenen dosyaları kullanıcıya anlaşılır bir tablo formatında sunar. Her dosya için aşağıdaki bilgiler görüntülenir:
Dosya Adı
Dosya Yolu
Boyut (KB, MB veya GB cinsinden)
Son Değiştirme Tarihi
Sürükle-Bırak Desteği
Dosyaları tabloya eklemek oldukça kolaydır. Kullanıcılar, bilgisayarlarındaki herhangi bir dosyayı sürükleyip uygulama penceresine bırakarak listeye ekleyebilir.
Gelişmiş Sağ Tık Menüsü
Kullanıcılar tablo üzerinde sağ tıkladıklarında açılan menü ile şunları yapabilir:
Seçili veya tüm dosyaları silme.
Tüm dosyaları hızlıca seçme veya seçimi kaldırma.
Tablodaki bilgileri dışarı aktarma:
Word (.docx)
Excel (.xlsx)
HTML (.html)
Tablo içeriğini hızlıca panoya kopyalama.
Boyut Birimini Dinamik Olarak Değiştirme
Kullanıcı, tablonun başlığındaki "Boyut" sütununa tıklayarak dosya boyutlarının görüntülenme birimini (KB, MB veya GB) hızlıca değiştirebilir.
Klavye Kısayolları ile Kolay Erişim
Uygulamada kullanılan klavye kısayolları şunlardır:
Ctrl + A: Tüm dosyaları seçme.
Delete: Tüm dosyaları silme.
Ctrl + Yukarı/Aşağı Ok: Satırlar arasında hızlı gezinme.
- Kolay Dışa Aktarma İşlemleri
Tablodaki verileri birkaç tıklamayla dışarı aktarabilir ve böylece raporlama veya dosya arşivleme işlemlerinde zaman tasarrufu sağlayabilirsiniz.
Uygulamanın Kullanım Alanları
Bu uygulama, sıkça dosyalarla çalışan herkes için idealdir:
İş yerlerinde belge yönetimi ve raporlama
Öğrenci ve akademisyenlerin dokümanlarını düzenleme ve arşivleme
Fotoğrafçılar, grafik tasarımcılar ve dijital içerik üreticileri için dosya organizasyonu
Sonuç olarak bu Python uygulaması, sade ve işlevsel yapısı sayesinde günlük dosya işlemlerini kolaylaştırarak kullanıcıların zaman ve emek tasarrufu yapmasını sağlar.
Kodun Tamamı:
import sys
import os
import csv
from datetime import datetime
from PyQt5.QtWidgets import (
QApplication, QMainWindow, QTableWidget, QTableWidgetItem,
QPushButton, QFileDialog, QVBoxLayout, QWidget, QMenu,
QAbstractItemView, QMessageBox
)
from PyQt5.QtCore import Qt, QPoint, QMimeData, QItemSelectionModel
from docx import Document
from openpyxl import Workbook
class FileTable(QTableWidget):
def __init__(self, parent=None, status_callback=None):
super().__init__(parent)
self.status_callback = status_callback
# Satır seçimi
self.setSelectionBehavior(QAbstractItemView.SelectRows)
self.setSelectionMode(QAbstractItemView.ExtendedSelection)
self.setMouseTracking(True)
# Sütunlar
self.setColumnCount(4)
self.setHorizontalHeaderLabels([
'Dosya Adı', 'Dosya Yolu', 'Boyut (KB)', 'Son Değiştirme'
])
self.horizontalHeader().setStretchLastSection(True)
# Düzenleme kapalı, sürükle bırak açık
self.setEditTriggers(QTableWidget.NoEditTriggers)
self.setAcceptDrops(True)
# Sağ tık menüsü
self.setContextMenuPolicy(Qt.CustomContextMenu)
self.customContextMenuRequested.connect(self.open_menu)
# Seçim değiştiğinde statusbar güncelle
self.itemSelectionChanged.connect(self.on_selection_changed)
# Boyut birimi dönüşümü
self.units = ['KB', 'MB', 'GB']
self.current_unit_index = 0
self.horizontalHeader().sectionClicked.connect(self.on_header_clicked)
def open_menu(self, pos: QPoint):
menu = QMenu(self)
sel_rows = sorted({idx.row() for idx in self.selectedIndexes()})
all_selected = len(sel_rows) == self.rowCount() and self.rowCount() > 0
delete_sel = menu.addAction("Seçili Satırları Sil")
if all_selected:
deselect = menu.addAction("Seçimi İptal Et")
else:
select_all = menu.addAction("Tüm Satırları Seç")
delete_all = menu.addAction("Tüm Satırları Sil")
exp_menu = menu.addMenu("Dışarı Aktar")
exp_word = exp_menu.addAction("Word")
exp_excel = exp_menu.addAction("Excel")
exp_html = exp_menu.addAction("HTML")
copy_action = menu.addAction("Tabloyu Kopyala")
action = menu.exec_(self.mapToGlobal(pos))
# İşlem bazlı yanıt
if action == delete_sel and sel_rows:
if QMessageBox.question(self, 'Uyarı',
'Seçili satırları silmek istediğinize emin misiniz?',
QMessageBox.Yes | QMessageBox.No) == QMessageBox.Yes:
for r in reversed(sel_rows):
self.removeRow(r)
self.status_callback(f"Toplam dosya: {self.rowCount()}")
elif 'select_all' in locals() and action == select_all:
self.selectAll()
elif 'deselect' in locals() and action == deselect:
self.clearSelection()
elif action == delete_all:
if QMessageBox.question(self, 'Uyarı',
'Tüm satırları silmek istediğinize emin misiniz?',
QMessageBox.Yes | QMessageBox.No) == QMessageBox.Yes:
self.setRowCount(0)
self.status_callback("Toplam dosya: 0")
elif action == exp_word:
path, _ = QFileDialog.getSaveFileName(
self, 'Word Olarak Kaydet', '', 'Word Docx (*.docx)'
)
if path:
self.export_to_word(path, sel_rows)
elif action == exp_excel:
path, _ = QFileDialog.getSaveFileName(
self, 'Excel Olarak Kaydet', '', 'Excel (*.xlsx)'
)
if path:
self.export_to_excel(path, sel_rows)
elif action == exp_html:
path, _ = QFileDialog.getSaveFileName(
self, 'HTML Olarak Kaydet', '', 'HTML (*.html)'
)
if path:
self.export_to_html(path, sel_rows)
elif action == copy_action:
self.copy_selection()
def on_selection_changed(self):
rows = self.selectionModel().selectedRows()
if rows:
path = self.item(rows[0].row(), 1).text()
self.status_callback(path)
def on_header_clicked(self, index):
if index == 2:
self.current_unit_index = (self.current_unit_index + 1) % len(self.units)
self.convert_sizes()
def convert_sizes(self):
unit = self.units[self.current_unit_index]
self.setHorizontalHeaderItem(2, QTableWidgetItem(f"Boyut ({unit})"))
for row in range(self.rowCount()):
item = self.item(row, 2)
size_bytes = item.data(Qt.UserRole) or 0
if unit == 'KB':
val = size_bytes / 1024
elif unit == 'MB':
val = size_bytes / (1024**2)
else:
val = size_bytes / (1024**3)
item.setText(f"{val:.2f}")
# Sürükle / Bırak
def dragEnterEvent(self, e):
if e.mimeData().hasUrls(): e.acceptProposedAction()
else: super().dragEnterEvent(e)
def dragMoveEvent(self, e):
if e.mimeData().hasUrls(): e.acceptProposedAction()
else: super().dragMoveEvent(e)
def dropEvent(self, e):
if e.mimeData().hasUrls():
for url in e.mimeData().urls():
self.add_file(url.toLocalFile())
e.acceptProposedAction()
else:
super().dropEvent(e)
def add_file(self, path: str):
if not os.path.isfile(path): return
# Çift kayıt engelle
for row in range(self.rowCount()):
if self.item(row,1).text() == path:
return
fi = os.stat(path)
size_bytes = fi.st_size
size_kb = size_bytes / 1024
mtime = datetime.fromtimestamp(fi.st_mtime).strftime("%Y-%m-%d %H:%M:%S")
r = self.rowCount()
self.insertRow(r)
items = [
QTableWidgetItem(os.path.basename(path)),
QTableWidgetItem(path),
QTableWidgetItem(f"{size_kb:.2f}"),
QTableWidgetItem(mtime)
]
for i, it in enumerate(items):
it.setToolTip(path)
if i == 2:
it.setData(Qt.UserRole, size_bytes)
self.setItem(r, i, it)
self.status_callback(f"Toplam dosya: {self.rowCount()}")
def keyPressEvent(self, e):
# CTRL+A
if e.key() == Qt.Key_A and e.modifiers() & Qt.ControlModifier:
self.selectAll(); return
# DELETE
if e.key() == Qt.Key_Delete and self.rowCount():
if QMessageBox.question(self, 'Uyarı',
'Tüm satırları silmek istediğinize emin misiniz?',
QMessageBox.Yes | QMessageBox.No) == QMessageBox.Yes:
self.setRowCount(0)
self.status_callback("Toplam dosya: 0")
return
# CTRL+↓
if e.key() == Qt.Key_Down and e.modifiers() & Qt.ControlModifier:
sel = self.selectionModel().selectedRows()
if not sel:
self.selectRow(0)
else:
m = max(s.row() for s in sel) + 1
if m < self.rowCount():
idx = self.model().index(m, 0)
self.selectionModel().select(idx, QItemSelectionModel.Select | QItemSelectionModel.Rows)
return
# CTRL+↑
if e.key() == Qt.Key_Up and e.modifiers() & Qt.ControlModifier:
sel = self.selectionModel().selectedRows()
if not sel:
self.selectRow(self.rowCount()-1)
else:
m = min(s.row() for s in sel) - 1
if m >= 0:
idx = self.model().index(m, 0)
self.selectionModel().select(idx, QItemSelectionModel.Select | QItemSelectionModel.Rows)
return
super().keyPressEvent(e)
def copy_selection(self):
rows = sorted({idx.row() for idx in self.selectedIndexes()})
if not rows: return
headers = [self.horizontalHeaderItem(c).text() for c in range(self.columnCount())]
# HTML tablosu
html = '<table border="1"><tr>' + ''.join(f'<th>{h}</th>' for h in headers) + '</tr>'
for r in rows:
html += '<tr>' + ''.join(f'<td>{self.item(r,c).text()}</td>' for c in range(self.columnCount())) + '</tr>'
html += '</table>'
# Düz metin
text = '\t'.join(headers) + '\n'
for r in rows:
text += '\t'.join(self.item(r,c).text() for c in range(self.columnCount())) + '\n'
md = QMimeData()
md.setHtml(html)
md.setText(text)
QApplication.clipboard().setMimeData(md)
def export_to_word(self, filename, sel_rows):
rows = sel_rows if sel_rows else list(range(self.rowCount()))
doc = Document()
table = doc.add_table(rows=1, cols=self.columnCount())
hdr_cells = table.rows[0].cells
for i in range(self.columnCount()):
hdr_cells[i].text = self.horizontalHeaderItem(i).text()
for r in rows:
row_cells = table.add_row().cells
for c in range(self.columnCount()):
row_cells[c].text = self.item(r, c).text()
doc.save(filename)
def export_to_excel(self, filename, sel_rows):
rows = sel_rows if sel_rows else list(range(self.rowCount()))
wb = Workbook()
ws = wb.active
ws.append([self.horizontalHeaderItem(c).text() for c in range(self.columnCount())])
for r in rows:
ws.append([self.item(r, c).text() for c in range(self.columnCount())])
wb.save(filename)
def export_to_html(self, filename, sel_rows):
rows = sel_rows if sel_rows else list(range(self.rowCount()))
headers = [self.horizontalHeaderItem(c).text() for c in range(self.columnCount())]
html = '<html><body><table border="1"><tr>' + ''.join(f'<th>{h}</th>' for h in headers) + '</tr>'
for r in rows:
html += '<tr>' + ''.join(f'<td>{self.item(r,c).text()}</td>' for c in range(self.columnCount())) + '</tr>'
html += '</table></body></html>'
with open(filename, 'w', encoding='utf-8') as f:
f.write(html)
def export_csv(self, filename):
with open(filename, 'w', newline='', encoding='utf-8') as f:
w = csv.writer(f)
w.writerow(['Dosya Adı', 'Dosya Yolu', 'Boyut (KB)', 'Son Değiştirme'])
for r in range(self.rowCount()):
w.writerow([self.item(r, c).text() for c in range(self.columnCount())])
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle('Gelişmiş Dosya Tablosu')
central = QWidget()
layout = QVBoxLayout(central)
self.btn_open = QPushButton('Dosya Seç...')
self.btn_export = QPushButton('CSV Olarak Dışa Aktar')
layout.addWidget(self.btn_open)
layout.addWidget(self.btn_export)
self.table = FileTable(status_callback=self.statusBar().showMessage)
layout.addWidget(self.table)
self.setCentralWidget(central)
self.btn_open.clicked.connect(self.open_files)
self.btn_export.clicked.connect(lambda: self.table.export_csv(
QFileDialog.getSaveFileName(self, 'CSV Kaydet', '', 'CSV (*.csv)')[0]
))
def open_files(self):
paths, _ = QFileDialog.getOpenFileNames(self, 'Dosya Seç', '', 'Tüm Dosyalar (*.*)')
for p in paths:
self.table.add_file(p)
if __name__ == '__main__':
app = QApplication(sys.argv)
win = MainWindow()
win.resize(800, 500)
win.show()
sys.exit(app.exec_())