Почему я не могу использовать переменное имя delclass?

#python #pyqt5

Вопрос:

Я создаю календарь с помощью pyqt5, и он выдает мне эту ошибку, когда я написал эти строки кода: from pyqt5 import QtCore, QtGui, QtWidgets, uic , и delclass = uic.loaduiType .

 Traceback (most recent call last):
  File "C:UsershungyDesktopMason WorksPythonProjectsCalender.py", line 7, in <module>
    delclass = uic.loadUiType('Del_btn.ui')
  File "C:UsershungyAppDataLocalProgramsPythonPython39libsite-packagesPyQt5uic__init__.py", line 204, in loadUiType
    exec(code_string.getvalue(), ui_globals)
  File "<string>", line 5
    def setupUi(self, del):
                      ^
SyntaxError: invalid syntax
 

Что не так с моим кодом?
Я попытался сменить имя на Delclass , но это не сработало.
Это мой код:

 import sys
from PyQt5 import QtCore, QtGui, QtWidgets, uic

# defines the formclasses
calclass = uic.loadUiType("Calender.ui")[0]
addclass = uic.loadUiType('Add_btn.ui')
delclass = uic.loadUiType('Del_btn.ui')
editclass = uic.loadUiType('Edit_btn.ui')
# classes
class Add(QtWidgets.QMainWindow, addclass):
    def __init__(self, parent=None):
        QtWidgets.QMainWindow.__init__(self, parent)
        self.setupUi(self)
        # self.Namevalue = Name_Text.value

class Calender(QtWidgets.QMainWindow, calclass):
    def __init__(self, parent=None):
        QtWidgets.QMainWindow.__init__(self, parent)
        self.setupUi(self)
        self.Add.triggered.connect(self.add_clicked)
        self.Delete.triggered.connect(self.del_clicked)
        self.Close_Exit.triggered.connect(self.x_clicked)

    def x_clicked(self):
        self.close()

    def del_clicked(self):
        pass

    def add_clicked(self):
        pass

app = QtWidgets.QApplication(sys.argv)
Window = Calender()
Window.show()
app.exec_()
 

.пользовательский интерфейс

 <?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>del</class>
 <widget class="QDialog" name="del">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>355</width>
    <height>106</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Del</string>
  </property>
  <property name="sizeGripEnabled">
   <bool>false</bool>
  </property>
  <widget class="QDialogButtonBox" name="OKCANCEL">
   <property name="geometry">
    <rect>
     <x>-80</x>
     <y>60</y>
     <width>341</width>
     <height>32</height>
    </rect>
   </property>
   <property name="orientation">
    <enum>Qt::Horizontal</enum>
   </property>
   <property name="standardButtons">
    <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
   </property>
  </widget>
  <widget class="QPushButton" name="Why">
   <property name="geometry">
    <rect>
     <x>10</x>
     <y>10</y>
     <width>93</width>
     <height>28</height>
    </rect>
   </property>
   <property name="text">
    <string>Why:</string>
   </property>
  </widget>
  <widget class="QPlainTextEdit" name="plainTextEdit">
   <property name="geometry">
    <rect>
     <x>120</x>
     <y>10</y>
     <width>191</width>
     <height>31</height>
    </rect>
   </property>
  </widget>
 </widget>
 <resources/>
 <connections>
  <connection>
   <sender>OKCANCEL</sender>
   <signal>accepted()</signal>
   <receiver>del</receiver>
   <slot>accept()</slot>
   <hints>
    <hint type="sourcelabel">
     <x>248</x>
     <y>254</y>
    </hint>
    <hint type="destinationlabel">
     <x>157</x>
     <y>274</y>
    </hint>
   </hints>
  </connection>
  <connection>
   <sender>OKCANCEL</sender>
   <signal>rejected()</signal>
   <receiver>del</receiver>
   <slot>reject()</slot>
   <hints>
    <hint type="sourcelabel">
     <x>316</x>
     <y>260</y>
    </hint>
    <hint type="destinationlabel">
     <x>286</x>
     <y>274</y>
    </hint>
   </hints>
  </connection>
 </connections>
</ui>
 

Комментарии:

1. Вы показываете нам ошибку del , а не delclass . Если у вас все еще есть ошибка delclass и вы больше не используете del ее , покажите нам эту ошибку вместо этого-потому del что это ключевое слово (и поэтому ожидается, что оно не сработает при использовании противоречивым образом), но delclass это не так.

2. delclass = uic.loaduiType это не проблема. def setupUi(self, del): вот в чем проблема.

3. Я не писал защиту setupUi(self, del): . Я импортировал pyqt5.

4. Я голосую за повторный ответ на этот вопрос: хотя del дублированные ответы верны, они не охватывают проблему использования защищенных ключевых слов в Qt Designer, который не знает о возможном использовании и частичных ограничениях PyQt (и python) для имен пользовательского интерфейса.

5. @ThePyGuy 1) Похоже, ОП никогда этого не писал, по крайней мере, это не показано в коде. 2) Я не могу воспроизвести проблему, поэтому, вероятно, если операция не предоставляет MRE, то лучшей причиной отключения является «опечатка или невоспроизводимость».

Ответ №1:

Судя по вашему коду, вы, вероятно, переименовали виджет верхнего уровня в Qt Designer как del .

Хотя это не представляет реальной проблемы с точки зрения Qt, она может стать таковой при использовании uic функций, которые создают необработанный файл python (или его «абстрактную» форму) при использовании loadUiType .

uic pyuic , который использует те же функции) создает функции и объекты на основе имен объектов пользовательского интерфейса. Среди них есть:

  • def setupUi(self, <object name of the form>) ;
  • def retranslateUi(self, <object name of the form>) ;

В результате, если вы назовете del свой объект верхнего уровня, функции будут:

  • def setupUi(self, del) ;
  • def retranslateUi(self, del) ;

Это, очевидно, вызовет исключение, так del как не может быть использовано подобным образом в python.

Имейте в виду, что то же самое справедливо для всех других защищенных слов python:

  • exec (хотя в последних версиях python это больше не проблема, все равно лучше избегать ее, аналогично print )
  • raise , assert
  • def , class
  • if , elif , else , not
  • for , while
  • continue , break
  • try , except , finally
  • и т.д…

Решение (которое действительно в любом случае) состоит в том, чтобы тщательно выбирать имена объектов: ищите описательные имена, а не короткие , так как они не имеют никакой практической пользы.
Вместо del этого предпочтите delButton (или del_button , если вы хотите сохранить стандартный стиль Python), или deleteButton .

Помните: ссылка на имя (или имя объекта в Qt) объекта всегда должна позволять вам с первого взгляда определить, что это за объект и что он делает.
Что делает «дел»? Удалить? Что удалить? Это функция или переменная? Это виджет? Если это виджет, то что это за виджет?

Откройте файл пользовательского интерфейса в конструкторе и соответствующим образом измените имя объекта верхнего уровня, а также убедитесь, что ни один другой виджет не использует эти защищенные имена, поскольку в любом случае они вызовут исключение (например, у вас не может быть объекта с именем self.raise ).

Комментарии:

1. Это действительно незначительная ошибка в конструкторе. На самом деле невозможно использовать такие имена, как if , else , for , break и т. Д., Потому что это зарезервированные ключевые слова C . Дизайнер автоматически добавляет такие имена, добавляя суффикс, поэтому он может дополнительно включать все другие ключевые слова Python (например, в качестве предпочтения или настройки формы). Инструмент uic уже может генерировать код Python (который можно просмотреть в конструкторе), так что это действительно должно поддерживаться.

2. @musicamante, Но я не вижу def setupUi(self, del) , потому что я импортировал pyqt5.

3. @MasonLin Пожалуйста, прочитайте мой ответ более внимательно: вы не можете «видеть» эти функции, они созданы внутренне uic.loadUiType . И, в любом случае, это не имеет значения: важно то, что вы НЕ должны называть объект «del» ни в python, ни в Qt Designer.

4. Если вы хотите его увидеть, просто запустите pyuic Del_btn.ui -o output.py из терминала/приглашения (при необходимости измените pyuic то, что у вас есть в вашей системе, в зависимости от установленной ОС и версий PyQt, это может быть: pyuic5 , pyuic5.bat и т. Д.). Затем вы увидите их def setupUi(self, del) в выходном файле.

5. @MasonLin Что вы имеете в виду под «Я не могу редактировать»?

Ответ №2:

del это зарезервированное слово в python. Он удаляет объект с del x помощью .

Например:

 >>> x = 5
>>> x
5
>>> del x
>>> x
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined