У меня не отображается QScrollArea вместе с виджетом, подскажите, что делать
main.py:
Python
class MainFrame(EasyMainWindow):
def __init__(self):
EasyMainWindow.__init__(self, "Terraria Mod Creator", (1000, 700))
self.mod = Mod()
self.add_gui()
self.items = list()
def add_item_to_list(self, item):
self.items.append(item)
self.__update__()
def add_gui(self):
menu_bar = QMenuBar()
file_menu = menu_bar.addMenu('&File')
new_menu = file_menu.addMenu('&New')
add_menu_item_and_bind(self, "&Project", self.on_new_project, new_menu, shortcut="Shift + Ctrl + N")
add_menu_item_and_bind(self, "&Weapon", self.on_new_weapon, new_menu)
add_menu_item_and_bind(self, "&Projectile", self.on_new_projectile, new_menu)
add_menu_item_and_bind(self, "&Ammo", self.on_new_ammo, new_menu)
add_menu_item_and_bind(self, "&Armor", self.on_new_armor, new_menu)
add_menu_item_and_bind(self, "&Hostile NPC", self.on_new_hostile_npc, new_menu)
import_menu = file_menu.addMenu("&Import")
add_menu_item_and_bind(self, "&Project", self.on_open_project, import_menu, shortcut="Shift + Ctrl + O")
mod_menu = menu_bar.addMenu("&Mod")
add_menu_item_and_bind(self, "&Convert to C#", self.on_convert_project, mod_menu, shortcut="Shift + Ctrl + C")
self.setMenuBar(menu_bar)
widget = QWidget()
self.setCentralWidget(widget)
layout = QHBoxLayout()
items_tab = QTabWidget()
self.items_list = QListWidget()
self.items_list.itemClicked.connect(self.__on_select_item__)
items_tab.addTab(self.items_list, "&Inspector")
layout.addWidget(items_tab)
w = QFrame()
self.edit_tab = QTabWidget()
self.scroll = QScrollArea()
self.scroll.setWidget(w)
self.editor_layout = QVBoxLayout()
w.setLayout(self.editor_layout)
self.edit_tab.addTab(self.scroll, "&Editor")
layout.addWidget(self.edit_tab)
widget.setLayout(layout)
def __update__(self):
self.items_list.clear()
for item in self.items:
self.items_list.addItem(item.name)
def __update_editor__(self):
self.edit_tab.removeTab(0)
self.scroll = QScrollArea()
w = QWidget()
self.scroll.setWidget(w)
w.setLayout(self.editor_layout)
self.edit_tab.addTab(self.scroll, "&Editor")
def __on_select_item__(self):
if self.editor_layout.count() > 0:
self.clear_layout(self.editor_layout)
item = self.items[self.items_list.currentRow()]
if type(item) is WeaponItem:
self.add_field(self.editor_layout, "Name:", EF_STYLE_TEXT_ENTRY)
self.add_field(self.editor_layout, "Description:", EF_STYLE_TEXT_ENTRY)
self.add_field(self.editor_layout, "Melee:", EF_STYLE_CHECK_BOX)
self.add_field(self.editor_layout, "Ranged:", EF_STYLE_CHECK_BOX)
self.add_field(self.editor_layout, "Magic:", EF_STYLE_CHECK_BOX)
self.add_field(self.editor_layout, "Summon:", EF_STYLE_CHECK_BOX)
self.add_field(self.editor_layout, "Thrown:", EF_STYLE_CHECK_BOX)
self.add_field(self.editor_layout, "Use time:", EF_STYLE_TEXT_ENTRY)
self.add_field(self.editor_layout, "Use style:", EF_STYLE_TEXT_ENTRY)
self.add_field(self.editor_layout, "No melee:", EF_STYLE_CHECK_BOX)
self.add_field(self.editor_layout, "Damage:", EF_STYLE_TEXT_ENTRY)
self.add_field(self.editor_layout, "Crit:", EF_STYLE_TEXT_ENTRY)
self.add_field(self.editor_layout, "Knock back:", EF_STYLE_TEXT_ENTRY)
self.add_field(self.editor_layout, "Mana:", EF_STYLE_TEXT_ENTRY)
self.add_field(self.editor_layout, "Width:", EF_STYLE_TEXT_ENTRY)
self.add_field(self.editor_layout, "Height:", EF_STYLE_TEXT_ENTRY)
self.add_field(self.editor_layout, "Auto reuse:", EF_STYLE_CHECK_BOX)
self.add_field(self.editor_layout, "Cost:", EF_STYLE_TEXT_ENTRY)
self.add_field(self.editor_layout, "Rarity:", EF_STYLE_TEXT_ENTRY)
self.add_field(self.editor_layout, "Expert:", EF_STYLE_CHECK_BOX)
self.add_field(self.editor_layout, "Projectile:", EF_STYLE_TEXT_ENTRY_WITH_BUTTON,
button_text="Choose", function=self.__on_projectile_choose__)
self.add_field(self.editor_layout, "Shoot speed:", EF_STYLE_TEXT_ENTRY)
self.add_field(self.editor_layout, "Sound:", EF_STYLE_TEXT_ENTRY_WITH_BUTTON, button_text="Choose",
function=self.__on_sound_choose__)
self.add_field(self.editor_layout, "Ammo:", EF_STYLE_COMBO_BOX, choices=["None",
"Gel",
"Arrow",
"Coin",
"FallenStar",
"Bullet",
"Sand",
"Dart",
"Rocket",
"Solution",
"Flare",
"Snowball",
"StyngerBolt",
"CandyCorn",
"JackOLantern",
"Stake",
"NailFriendly"])
self.__update_editor__()
def __on_projectile_choose__(self):
dialog = ChooseProjectileDialog(self)
res = dialog.show_modal()
if res == 1:
return dialog.get_field_value("Projectiles:")
return -1
def __on_sound_choose__(self):
dialog = ChooseItemSoundDialog(self)
res = dialog.show_modal()
if res == 1:
return dialog.get_field_value("Sounds:")
return -1
if __name__ == '__main__':
app = QApplication(sys.argv)
frame = MainFrame()
frame.show()
sys.exit(app.exec_())
dialogs.py:
Python
from PyQt5.QtWidgets import QMainWindow, QWidget, QLineEdit, QCheckBox,\
QComboBox, QListWidget, QPushButton, QLabel,\
QVBoxLayout, QHBoxLayout, QFileDialog, QDialog
from PyQt5.QtCore import QSize
from PyQt5.QtCore import Qt
EF_STYLE_TEXT_ENTRY = 0
EF_STYLE_CHECK_BOX = 1
EF_STYLE_DIR_PICKER = 2
EF_STYLE_COMBO_BOX = 3
EF_STYLE_LIST = 4
EF_STYLE_TEXT_ENTRY_WITH_BUTTON = 5
class EasyField:
def __init__(self, parent: QWidget, text: str, style: int, position: int,
layout, button_text: str = "",
choices: list = None, function=None) -> None:
self.name = text
self.parent = parent
self.style = style
self.function = function
if style is EF_STYLE_DIR_PICKER:
hlayout = QHBoxLayout()
hlayout.addWidget(QLabel(text))
self.__field__ = QLineEdit()
hlayout.addWidget(self.__field__)
choose_path_button = QPushButton("Choose")
choose_path_button.clicked.connect(self.__on_choose_path__)
hlayout.addWidget(choose_path_button)
layout.insertLayout(position, hlayout)
elif style is EF_STYLE_TEXT_ENTRY:
hlayout = QHBoxLayout()
hlayout.addWidget(QLabel(text))
self.__field__ = QLineEdit()
hlayout.addWidget(self.__field__)
layout.insertLayout(position, hlayout)
elif style is EF_STYLE_CHECK_BOX:
hlayout = QHBoxLayout()
hlayout.addWidget(QLabel(text))
self.__field__ = QCheckBox()
hlayout.addWidget(self.__field__)
layout.insertLayout(position, hlayout)
elif style is EF_STYLE_TEXT_ENTRY_WITH_BUTTON:
hlayout = QHBoxLayout()
hlayout.addWidget(QLabel(text))
self.__field__ = QLineEdit()
hlayout.addWidget(self.__field__)
button = QPushButton(button_text)
button.clicked.connect(self.__handler__)
hlayout.addWidget(button)
layout.insertLayout(position, hlayout)
elif style is EF_STYLE_COMBO_BOX:
hlayout = QHBoxLayout()
hlayout.addWidget(QLabel(text))
self.__field__ = QComboBox()
for choice in choices:
self.__field__.addItem(choice)
hlayout.addWidget(self.__field__)
layout.insertLayout(position, hlayout)
elif style is EF_STYLE_LIST:
hlayout = QHBoxLayout()
hlayout.addWidget(QLabel(text))
self.__field__ = QListWidget()
for choice in choices:
self.__field__.addItem(choice)
hlayout.addWidget(self.__field__)
layout.insertLayout(position, hlayout)
def get_value(self):
if self.style is EF_STYLE_CHECK_BOX:
return self.__field__.isChecked()
elif self.style is EF_STYLE_DIR_PICKER:
return self.__field__.text()
elif self.style is EF_STYLE_TEXT_ENTRY:
return self.__field__.text()
elif self.style is EF_STYLE_TEXT_ENTRY_WITH_BUTTON:
return self.__field__.text()
elif self.style is EF_STYLE_COMBO_BOX:
return self.__field__.currentText()
elif self.style is EF_STYLE_LIST:
return self.__field__.currentRow()
def set_value(self, value) -> None:
if self.style is EF_STYLE_CHECK_BOX:
self.__field__.setCheckState(value)
elif self.style is EF_STYLE_DIR_PICKER:
self.__field__.setText(value)
elif self.style is EF_STYLE_TEXT_ENTRY:
self.__field__.setText(value)
elif self.style is EF_STYLE_TEXT_ENTRY_WITH_BUTTON:
self.__field__.setText(value)
elif self.style is EF_STYLE_COMBO_BOX or self.style is EF_STYLE_LIST:
return
def __handler__(self):
res = self.function()
self.set_value(str(res))
def __on_choose_path__(self):
result = QFileDialog.getExistingDirectoryUrl(self.parent)
self.__field__.setText(result.toString().replace("file:///", ""))
class EasyDialog(QDialog):
def __init__(self, parent, title: str):
QDialog.__init__(self, parent)
self.setWindowTitle(title)
self.closed = False
self.__id__ = 0
self.__fields_count__ = 0
self.__fields__ = []
self.__alt_fields_value__ = {}
self.layout = QVBoxLayout()
btn_sizer = QHBoxLayout()
ok_btn = QPushButton()
ok_btn.setText("Ok")
ok_btn.clicked.connect(self.__on_ok__)
cancel_btn = QPushButton()
cancel_btn.setText("Cancel")
cancel_btn.clicked.connect(self.__on_cancel__)
btn_sizer.addWidget(ok_btn)
btn_sizer.addWidget(cancel_btn)
self.layout.addLayout(btn_sizer)
self.setLayout(self.layout)
def add_field(self, text: str, style: int, button_text: str = "",
function=None, choices: list = None):
self.__fields__.append(EasyField(self, text, style,
self.__fields_count__,
self.layout, button_text=button_text,
function=function, choices=choices))
self.__fields_count__ += 1
def clear_layout(self):
while self.layout.count():
child = self.layout.takeAt(0)
if child.widget():
child.widget().deleteLater()
def on_close(self):
pass
def __on_ok__(self):
for field in self.__fields__:
if field.get_value() == "":
return
self.close()
self.__id__ = 1
def __on_cancel__(self):
self.close()
self.__id__ = -1
def reject(self):
self.closed = True
for field in self.__fields__:
self.__alt_fields_value__.update({field.name: field.get_value()})
if self.__id__ == 0:
self.__id__ = -1
#self.on_close()
QDialog.reject(self)
def get_field_value(self, name: str):
if not self.closed:
for field in self.__fields__:
if field.name == name:
return field.get_value()
else:
return self.__alt_fields_value__.get(name)
return -1
def set_field_value(self, name: str, value):
for field in self.__fields__:
if field.name == name:
field.set_value(value)
return -1
def show_modal(self):
self.exec()
return self.__id__
class EasyMainWindow(QMainWindow):
def __init__(self, title: str, size: tuple):
QMainWindow.__init__(self)
self.setWindowTitle(title)
self.setMinimumSize(QSize(size[0], size[1]))
self.closed = False
self.__fields_count__ = 0
self.__fields__ = []
self.__alt_fields_value__ = {}
def add_field(self, layout, text: str, style: int, button_text: str = "",
function=None, choices: list = None):
self.__fields__.append(EasyField(self, text, style,
self.__fields_count__,
layout, button_text=button_text,
function=function, choices=choices))
self.__fields_count__ += 1
def closeEvent(self, evt):
self.closed = True
for field in self.__fields__:
self.__alt_fields_value__.update({field.name: field.get_value()})
QMainWindow.closeEvent(self, evt)
def clear_layout(self, layout):
while layout.count():
child = layout.takeAt(0)
if child.widget():
child.widget().deleteLater()
def get_field_value(self, name: str):
if not self.closed:
for field in self.__fields__:
if field.name == name:
return field.get_value()
else:
return self.__alt_fields_value__.get(name)
return -1
def set_field_value(self, name: str, value):
for field in self.__fields__:
if field.name == name:
field.set_value(value)
return -1