QSplitter هو ويدجت يضع داخل النافذة مجموعة من الحاويات (widgets) بطريقة أفقية أو عمودية، ويمنح المستخدم مقابض قابلة للسحب لتغيير حجم كل قسم. مفيد لتصميم واجهات مثل: محرر (قائمة ملفات ← محرر نص)، أو لوحة إعدادات ← معاينة، أو أي تخطيط يحتاج أقسامًا قابلة لإعادة التحجيم.
متى نستخدم QSplitter؟
- عندما تريد أن تسمح للمستخدم بتغيير مساحة كل جزء من الواجهة ديناميكيًا.
- لتصميم واجهات شبيهة ببيئات التطوير (IDE) أو مستعرضات الملفات.
- لعمل تخطيطات أفقيّة أو عمودية قابلة للتعديل بسهولة.
المكتبات المطلوبة
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QTextEdit, QListWidget, QSplitter, QLabel
from PyQt5.QtCore import Qt
مثال عملي بسيط — محرر نص مع شريط جانبي قابل للسحب
الكود التالي يُنشئ نافذة فيها QListWidget على اليسار (قائمة ملفات وهمية) و QTextEdit على اليمين (منطقة التحرير). بينهما QSplitter يمكن سحب المقسم لتغيير العرض.
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QTextEdit, QListWidget, QSplitter, QLabel
from PyQt5.QtCore import Qt
class SplitterExample(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("مثال QSplitter - محرر بسيط")
self.resize(800, 500)
main_layout = QVBoxLayout()
# عنوان
header = QLabel("محرر بسيط — جرّ المقبض لتغيير المساحة بين اللوحين")
header.setStyleSheet("font-weight: bold; padding: 6px;")
main_layout.addWidget(header)
# إنشاء الوديجات
file_list = QListWidget()
file_list.addItems([f"ملف_{i}.txt" for i in range(1, 11)])
editor = QTextEdit()
editor.setPlainText("اكتب هنا...")
# إنشاء QSplitter أفقي بين القائمتين
splitter = QSplitter(Qt.Horizontal)
splitter.addWidget(file_list)
splitter.addWidget(editor)
# إعداد نسبة البداية (اختياري)
splitter.setSizes([200, 600]) # أجزاء افتراضية: القائمة أصغر من المحرر
main_layout.addWidget(splitter)
self.setLayout(main_layout)
if __name__ == "__main__":
app = QApplication(sys.argv)
win = SplitterExample()
win.show()
sys.exit(app.exec_())
ملاحظات على الكود
QSplitter(Qt.Horizontal) ينشئ تقسيمًا أفقيًا (أعمدة). استخدم Qt.Vertical للحصول على صفوف قابلة للسحب.addWidget() لإضافة كل قسم داخل الـ splitter.setSizes([a, b, ...]) يحدد أحجامًا مبدئية نسبية للأقسام.- كل ويدجت داخل الـ splitter يحتفظ بقدرته على التصغير/التكبير تلقائيًا.
أفكار متقدمة وإعدادات مفيدة
splitter.handleWidth() لتغيير عرض المقبض.splitter.setChildrenCollapsible(False) لمنع انهيار أحد الأقسام عند سحب المقبض لحدود الصفر.- يمكنك وضع splitter داخل splitter (داخل واحد آخر) لبناء تخطيطات معقدة — مثلاً عمود أيمن مقسّم إلى قسمين عموديين داخليًا.
- حفظ أو استرجاع حجم الأقسام (
splitter.sizes()) لتذكر حالة الواجهة بين جلسات المستخدم.
تمرين عملي (مع الحل) — محرر ثنائي مع معاينة HTML
المطلوب: أنشئ نافذة تحتوي على:
- محرر نص (QTextEdit) في الجهة اليسرى لإدخال كود HTML.
- نافذة معاينة بسيطة على اليمين تعرض نص HTML كـ نص منسّق (نستخدم QTextEdit بوضع read-only وندخل HTML باستخدام
setHtml()). - استخدم
QSplitterأفقيًا بحيث يمكن سحب المقسم بين المحرر والمعاينة. - عند كل تغير في المحرر (textChanged) يحدث العرض في المعاينة فورًا.
الحل
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QTextEdit, QSplitter
from PyQt5.QtCore import Qt
class HtmlLivePreview(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("محرر HTML مع معاينة مباشرة")
self.resize(900, 600)
layout = QVBoxLayout()
# محرر HTML
self.editor = QTextEdit()
self.editor.setPlainText("<h2>عنوان</h2>\n<p>جرب تحرير هذا النص...</p>")
# معاينة HTML (وضع للقراءة فقط)
self.preview = QTextEdit()
self.preview.setReadOnly(True)
self.preview.setHtml(self.editor.toPlainText()) # معاينة أولية
# QSplitter ليجعل المحرر والمعاينة قابلين لتغيير الحجم
splitter = QSplitter(Qt.Horizontal)
splitter.addWidget(self.editor)
splitter.addWidget(self.preview)
splitter.setSizes([500, 400])
# ربط تغيّر المحرر بتحديث المعاينة
self.editor.textChanged.connect(self.update_preview)
layout.addWidget(splitter)
self.setLayout(layout)
def update_preview(self):
# تحديث المعاينة بالمحتوى الحالي (كمحتوى HTML)
html_content = self.editor.toPlainText()
self.preview.setHtml(html_content)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = HtmlLivePreview()
window.show()
sys.exit(app.exec_())
تحدي إضافي (اقتراح)
اجعل التطبيق أعلاه يدعم:
- حفظ أحجام الأقسام في ملف إعدادات (مثلاً JSON) عند الإغلاق، واستعادتها عند الفتح.
- إضافة زر إخفاء / إظهار الشريط الجانبي (list) بحيث يستخدم
splitter.widget(i).hide()أوshow()ويعيد ضبط الأحجام بشكل سلس. - استبدال
QTextEditللمعاينة بـQWebEngineViewلعرض HTML حقيقي مع دعم CSS/JS (يتطلب تثبيت PyQtWebEngine).
خاتمة سريعة
QSplitter أداة بسيطة لكنها قوية لبناء واجهات مرنة وسهلة الاستخدام. استخدامها بشكل ذكي (مع حفظ حالة الواجهة وإتاحة إظهار/إخفاء الأقسام) يزيد من احترافية واجهاتك ويعطي تجربة مستخدم ممتازة — وكل هذا دون تكرار الدروس السابقة لأن الفكرة هنا مختلفة: التحكم بالتخطيط الديناميكي وليس بعرض قيمة واحدة أو حفظ بيانات.

