#python #pyqt5
#python #pyqt5
Вопрос:
Я пытаюсь создать довольно сложное приложение с графическим интерфейсом, используя PyQt5 и python 3.8, и я застрял на том, как разделить код на управляемые файлы. Я новичок в программировании с графическим интерфейсом и объектно-ориентированном программировании в целом и перепробовал несколько решений, которые смог найти в Интернете, но ни одно из них не работало на меня. Поэтому я прошу прощения, если этот вопрос задавался много раз раньше, но я думаю, что мне нужны некоторые подсказки, специально адаптированные к моему проекту.
Мне пока не разрешено публиковать изображения, поэтому вот ссылка, как выглядит приложение вместо этого: графический интерфейс приложения
В моем приложении есть боковая панель, которая всегда видна, и многоуровневый виджет, который содержит несколько страниц (видимый по ссылке выше — 14 WEL). У меня есть один main.py файл, который я хочу использовать для настройки пользовательского интерфейса и подключения кнопок всех страниц. Затем я хотел бы иметь несколько файлов .py для обработки пользовательского ввода и вычислений (по одному файлу на страницу). У меня также есть helper_functions.py файл для хранения нужных мне функций более чем на одной странице. Что сработало до сих пор, так это импортировать класс страницы (например, OutWelPageControl) в класс MainWindow в init, но тогда я, похоже, не могу вызвать createPreview() из GetFile() в OutWelPageControl (приложение завершается с кодом = 1073741845, когда я нажимаю кнопку, которая запускает GetFile()). Без вызова createPreview(self, welFiles_num) это действительно работает.
main.py:
import sys
import os
from PyQt5 import QtWidgets as qtw
from PyQt5 import QtCore as qtc
from PyQt5 import QtGui as qtg
from helper_functions import *
# GUI FILE
from ui_main import Ui_MainWindow
class MainWindow(qtw.QMainWindow):
def __init__(self):
qtw.QMainWindow.__init__(self)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
## PAGE CONNECTION
########################################################################
self.ui.btn_out_wel.clicked.connect(lambda: self.ui.stackedWidget.setCurrentWidget(self.ui.page_out_wel))
#... (other pages)
# This is probably wrong
from out_wel import OutWelPageControl
## BUTTONS
# How I want it to work
self.ui.btn_file.clicked.connect(lambda: OutWelPageControl.getFile(self))
self.show()
if __name__ == "__main__":
app = qtw.QApplication(sys.argv)
window = MainWindow()
sys.exit(app.exec_())
helper_functions.py:
from main import *
class HelperFunctions(MainWindow):
def getFile(self):
fnames = qtw.QFileDialog.getOpenFileNames(self, 'WEL-Datei öffnen', 'C:\',"*.WEL")[0]
return (fnames)
Страница out_wel.py:
from main import *
from helper_functions import *
class OutWelPageControl(MainWindow):
def getFile(self):
welFiles = HelperFunctions.getFile(self)
# Label Input File
welFiles_string = []
for wel in welFiles:
welFiles_string.append(os.path.basename(wel))
welFiles_string2 = ', '.join(welFiles_string)
self.ui.lbl_filepath.setText(welFiles_string2)
welFiles_num = []
for wel in welFiles:
welFiles_num.append(os.path.splitext(os.path.basename(wel))[0])
# Call another function
createPreview(self, welFiles_num)
def createPreview(self, welFiles_num):
pass
Итак, мой вопрос в основном заключается в том, как я могу разделить код приложения, чтобы каждая страница имела свой собственный файл .py и при этом могла изменять элементы пользовательского интерфейса? Должны ли файлы страниц содержать подклассы MainWindow или есть другой вариант, чтобы заставить его работать?
Ответ №1:
Здесь довольно много кода без какой-либо конкретной проблемы, но я могу попытаться дать несколько общих советов и посмотреть, поможет ли это вам каким-либо образом.
- В helper_functions вы не можете иметь
from main import *
as при импорте helper_functions в main, это приводит к циклическому импорту (они импортируют друг друга снова и снова) - Также в helper_functions это не обязательно должен быть класс, если все, что вам нужно, это несколько функций, доступных на разных страницах. Вы можете просто иметь там функции и вызывать их с помощью
helper_functions.func_name(args)
. from out_wel import OutWelPageControl
должно быть в верхней части файла .py, а не внутри инициализации основного класса- Для импорта и использования кода пользовательского интерфейса используйте двойное наследование, чтобы вам не приходилось использовать
self.ui
везде:
class MainWindow(qtw.QMainWindow, Ui_MainWindow):
def __init__(self, *args, **kwargs):
super().__init__(self, *args, **kwargs)
self.setup_ui()
- Вы не должны создавать подклассы своего основного класса в других классах, которые вы создали для разных страниц.
- Я хотел бы взглянуть на эту страницу о том, как использовать сложенные виджеты. Но я полагаю, что вам нужно было бы подклассировать QWidget для ваших разных классов «страниц», чтобы они были виджетами, которые вы могли добавить в виджет с накоплением.
- Если вы создаете классы, вы должны создавать экземпляры объектов, например, в main вы должны иметь
self.out_wel_page = OutwelPageControl()
- Если вам нужна какая-то функциональность родительского виджета в функции дочернего виджета, вы всегда можете перейти
self
от родительского виджета к дочернему
Дайте мне знать, если что-нибудь из этого помогло, не смог найти что-то конкретное, чтобы исправить проблемы, с которыми вы столкнулись, но хотел попытаться помочь.
Комментарии:
1. Большое спасибо, я ценю любые предложения! Я подробнее рассмотрю ссылку, которую вы предложили, я чувствую, что есть много вещей, которых я еще не знаю. Я не обязательно хочу создавать подклассы, если есть лучший способ сделать это. Теперь я использовал функции как для функций helper_functions, так и для функций страницы, и, похоже, это работает! Поэтому я отмечаю этот вопрос как решенный. Пункт 7: отсутствуют ли скобки OutwelPageControl(), или это какая-то концепция, с которой я еще не знаком? Еще раз спасибо, что указали мне правильное направление!
2. Рад быть хоть немного полезным, все это очень пугает при обучении кодированию, так как есть чему поучиться, и я могу многое понять. И нет, хороший улов, он предназначен для того, чтобы иметь скобки, которые я отредактирую