تقنيات نور التعليمية تقنيات نور التعليمية
في الوقت الحالي

جاري صيانة و تحديث للمدونة

في الوقت الحالي
جاري التحميل ...

الدرس 27 – QTabWidget

في هذا الدرس سنتعرف على QTabWidget، وهو عنصر واجهة رسومية يسمح بعرض محتويات في شكل تبويبات (Tabs)، بحيث يمكن للمستخدم التنقل بين الصفحات بسهولة مثل متصفح الإنترنت أو إعدادات البرامج.

QTabWidget

أهم خصائص QTabWidget

  • إضافة تبويب جديد:

    tab_widget.addTab(عنصر, "عنوان التبويب")
    
  • تغيير عنوان التبويب:

    tab_widget.setTabText(رقم_التبويب, "عنوان جديد")
    
  • الوصول للتبويب الحالي:

    index = tab_widget.currentIndex()
    
  • تغيير التبويب الحالي:

    tab_widget.setCurrentIndex(رقم_التبويب)
    

مثال عملي

هذا المثال يحتوي على 3 تبويبات: الصفحة الرئيسية، الإعدادات، حول البرنامج.

import sys
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QLabel, QTabWidget

class TabExample(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("مثال QTabWidget")
        self.resize(400, 300)

        layout = QVBoxLayout()

        # إنشاء التبويبات
        tabs = QTabWidget()

        # التبويب الأول
        tab1 = QWidget()
        tab1_layout = QVBoxLayout()
        tab1_layout.addWidget(QLabel("مرحبًا بك في الصفحة الرئيسية"))
        tab1.setLayout(tab1_layout)

        # التبويب الثاني
        tab2 = QWidget()
        tab2_layout = QVBoxLayout()
        tab2_layout.addWidget(QLabel("هنا الإعدادات"))
        tab2.setLayout(tab2_layout)

        # التبويب الثالث
        tab3 = QWidget()
        tab3_layout = QVBoxLayout()
        tab3_layout.addWidget(QLabel("حول البرنامج: إصدار 1.0"))
        tab3.setLayout(tab3_layout)

        # إضافة التبويبات
        tabs.addTab(tab1, "الرئيسية")
        tabs.addTab(tab2, "الإعدادات")
        tabs.addTab(tab3, "حول")

        layout.addWidget(tabs)
        self.setLayout(layout)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = TabExample()
    window.show()
    sys.exit(app.exec_())

شرح الكود

  1. أنشأنا عنصر QTabWidget لاحتواء التبويبات.

  2. أضفنا 3 صفحات (QWidget) مع تخطيطات خاصة بها.

  3. وضعنا كل صفحة داخل التبويب المناسب.

  4. أضفنا النصوص لشرح محتوى كل تبويب.


📌 معلومة إضافية:
يمكنك إضافة أي عنصر داخل التبويب، مثل أزرار، جداول، أو حتى تبويبات داخل تبويبات.


تمرين شامل على QTabWidget بحيث:

  • التبويب الأول: إدخال بيانات (الاسم – العمر – الدرجة) مع زر إضافة للجدول.

  • التبويب الثاني: عرض البيانات في QTableWidget.

  • التبويب الثالث: زر لحفظ الجدول في ملف Excel.


الكود

import sys
import os
import pandas as pd
from PyQt5.QtWidgets import (
    QApplication, QWidget, QVBoxLayout, QTabWidget,
    QLabel, QLineEdit, QPushButton, QHBoxLayout,
    QTableWidget, QTableWidgetItem, QMessageBox
)

class TabApp(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("تمرين شامل على QTabWidget")
        self.resize(600, 400)

        self.excel_file = "students_data.xlsx"

        layout = QVBoxLayout()

        # إنشاء QTabWidget
        self.tabs = QTabWidget()

        # التبويب الأول - إدخال البيانات
        self.tab1 = QWidget()
        tab1_layout = QVBoxLayout()

        form_layout = QHBoxLayout()
        self.name_input = QLineEdit()
        self.name_input.setPlaceholderText("ادخل الاسم")
        self.age_input = QLineEdit()
        self.age_input.setPlaceholderText("ادخل العمر")
        self.grade_input = QLineEdit()
        self.grade_input.setPlaceholderText("ادخل الدرجة")

        form_layout.addWidget(self.name_input)
        form_layout.addWidget(self.age_input)
        form_layout.addWidget(self.grade_input)

        btn_add = QPushButton("إضافة إلى الجدول")
        btn_add.clicked.connect(self.add_to_table)

        tab1_layout.addLayout(form_layout)
        tab1_layout.addWidget(btn_add)
        self.tab1.setLayout(tab1_layout)

        # التبويب الثاني - عرض الجدول
        self.tab2 = QWidget()
        tab2_layout = QVBoxLayout()
        self.table = QTableWidget()
        self.table.setColumnCount(3)
        self.table.setHorizontalHeaderLabels(["الاسم", "العمر", "الدرجة"])
        tab2_layout.addWidget(self.table)
        self.tab2.setLayout(tab2_layout)

        # تحميل البيانات من Excel إذا موجود
        self.load_from_excel()

        # التبويب الثالث - حفظ البيانات
        self.tab3 = QWidget()
        tab3_layout = QVBoxLayout()
        btn_save = QPushButton("حفظ البيانات في Excel")
        btn_save.clicked.connect(self.save_to_excel)
        tab3_layout.addWidget(QLabel("اضغط الزر لحفظ جميع البيانات في ملف Excel"))
        tab3_layout.addWidget(btn_save)
        self.tab3.setLayout(tab3_layout)

        # إضافة التبويبات
        self.tabs.addTab(self.tab1, "إدخال البيانات")
        self.tabs.addTab(self.tab2, "عرض البيانات")
        self.tabs.addTab(self.tab3, "حفظ البيانات")

        layout.addWidget(self.tabs)
        self.setLayout(layout)

    def add_to_table(self):
        name = self.name_input.text()
        age = self.age_input.text()
        grade = self.grade_input.text()

        if not name or not age or not grade:
            QMessageBox.warning(self, "خطأ", "يرجى إدخال جميع البيانات")
            return

        row_position = self.table.rowCount()
        self.table.insertRow(row_position)
        self.table.setItem(row_position, 0, QTableWidgetItem(name))
        self.table.setItem(row_position, 1, QTableWidgetItem(age))
        self.table.setItem(row_position, 2, QTableWidgetItem(grade))

        self.name_input.clear()
        self.age_input.clear()
        self.grade_input.clear()

    def save_to_excel(self):
        rows = self.table.rowCount()
        cols = self.table.columnCount()
        data = []

        for row in range(rows):
            row_data = []
            for col in range(cols):
                item = self.table.item(row, col)
                row_data.append(item.text() if item else "")
            data.append(row_data)

        df = pd.DataFrame(data, columns=["الاسم", "العمر", "الدرجة"])
        df.to_excel(self.excel_file, index=False)
        QMessageBox.information(self, "تم الحفظ", f"تم حفظ البيانات في {self.excel_file}")

    def load_from_excel(self):
        if os.path.exists(self.excel_file):
            df = pd.read_excel(self.excel_file)
            self.table.setRowCount(len(df))
            for row in range(len(df)):
                for col in range(len(df.columns)):
                    self.table.setItem(row, col, QTableWidgetItem(str(df.iat[row, col])))

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = TabApp()
    window.show()
    sys.exit(app.exec_())

شرح الفكرة

  • التبويب الأول: إدخال بيانات الطالب.

  • التبويب الثاني: عرض جميع البيانات في جدول.

  • التبويب الثالث: حفظ البيانات في ملف Excel.

  • عند فتح البرنامج يتم تحميل البيانات من الملف إذا كان موجود.


سأطور لك التمرين بحيث:

  • عند إضافة أي صف جديد أو تعديل أي خلية أو حذف صف يتم حفظ الجدول مباشرة في ملف Excel.

  • عند تشغيل البرنامج يتم تحميل البيانات من الملف تلقائيًا إذا كان موجودًا.


الكود المطور – الحفظ التلقائي

import sys
import os
import pandas as pd
from PyQt5.QtWidgets import (
    QApplication, QWidget, QVBoxLayout, QTabWidget,
    QLabel, QLineEdit, QPushButton, QHBoxLayout,
    QTableWidget, QTableWidgetItem, QMessageBox
)

class TabApp(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("QTabWidget - حفظ تلقائي في Excel")
        self.resize(600, 400)

        self.excel_file = "students_data.xlsx"

        layout = QVBoxLayout()

        # إنشاء QTabWidget
        self.tabs = QTabWidget()

        # التبويب الأول - إدخال البيانات
        self.tab1 = QWidget()
        tab1_layout = QVBoxLayout()

        form_layout = QHBoxLayout()
        self.name_input = QLineEdit()
        self.name_input.setPlaceholderText("ادخل الاسم")
        self.age_input = QLineEdit()
        self.age_input.setPlaceholderText("ادخل العمر")
        self.grade_input = QLineEdit()
        self.grade_input.setPlaceholderText("ادخل الدرجة")

        form_layout.addWidget(self.name_input)
        form_layout.addWidget(self.age_input)
        form_layout.addWidget(self.grade_input)

        btn_add = QPushButton("إضافة إلى الجدول")
        btn_add.clicked.connect(self.add_to_table)

        tab1_layout.addLayout(form_layout)
        tab1_layout.addWidget(btn_add)
        self.tab1.setLayout(tab1_layout)

        # التبويب الثاني - عرض الجدول
        self.tab2 = QWidget()
        tab2_layout = QVBoxLayout()
        self.table = QTableWidget()
        self.table.setColumnCount(3)
        self.table.setHorizontalHeaderLabels(["الاسم", "العمر", "الدرجة"])
        tab2_layout.addWidget(self.table)
        self.tab2.setLayout(tab2_layout)

        # التبويب الثالث - معلومات الحفظ
        self.tab3 = QWidget()
        tab3_layout = QVBoxLayout()
        tab3_layout.addWidget(QLabel("📌 يتم حفظ البيانات تلقائيًا عند أي تعديل أو إضافة"))
        self.tab3.setLayout(tab3_layout)

        # إضافة التبويبات
        self.tabs.addTab(self.tab1, "إدخال البيانات")
        self.tabs.addTab(self.tab2, "عرض البيانات")
        self.tabs.addTab(self.tab3, "معلومات")

        layout.addWidget(self.tabs)
        self.setLayout(layout)

        # تحميل البيانات من Excel إذا موجود
        self.load_from_excel()

        # حفظ تلقائي عند تعديل أي خلية
        self.table.itemChanged.connect(self.save_to_excel)

    def add_to_table(self):
        name = self.name_input.text()
        age = self.age_input.text()
        grade = self.grade_input.text()

        if not name or not age or not grade:
            QMessageBox.warning(self, "خطأ", "يرجى إدخال جميع البيانات")
            return

        row_position = self.table.rowCount()
        self.table.insertRow(row_position)
        self.table.setItem(row_position, 0, QTableWidgetItem(name))
        self.table.setItem(row_position, 1, QTableWidgetItem(age))
        self.table.setItem(row_position, 2, QTableWidgetItem(grade))

        # مسح الحقول
        self.name_input.clear()
        self.age_input.clear()
        self.grade_input.clear()

        # حفظ تلقائي بعد الإضافة
        self.save_to_excel()

    def save_to_excel(self):
        rows = self.table.rowCount()
        cols = self.table.columnCount()
        data = []

        for row in range(rows):
            row_data = []
            for col in range(cols):
                item = self.table.item(row, col)
                row_data.append(item.text() if item else "")
            data.append(row_data)

        df = pd.DataFrame(data, columns=["الاسم", "العمر", "الدرجة"])
        df.to_excel(self.excel_file, index=False)

    def load_from_excel(self):
        if os.path.exists(self.excel_file):
            df = pd.read_excel(self.excel_file)
            self.table.setRowCount(len(df))
            for row in range(len(df)):
                for col in range(len(df.columns)):
                    self.table.setItem(row, col, QTableWidgetItem(str(df.iat[row, col])))

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = TabApp()
    window.show()
    sys.exit(app.exec_())

التطويرات المضافة

  1. الحفظ التلقائي يتم عند:

    • إضافة صف جديد.

    • تعديل أي خلية في الجدول.

  2. تحميل البيانات يتم مباشرة عند بدء البرنامج.

  3. التبويب الثالث يوضح للمستخدم أن البيانات تحفظ تلقائيًا.

عن الكاتب

Tamer Ahmed

التعليقات


اتصل بنا

إذا أعجبك محتوى مدونتنا نتمنى البقاء على تواصل دائم ، فقط قم بإدخال بريدك الإلكتروني للإشتراك في بريد المدونة السريع ليصلك جديد المدونة أولاً بأول ، كما يمكنك إرسال رساله بالضغط على الزر المجاور ...

جميع الحقوق محفوظة

تقنيات نور التعليمية