почему я pyqt5 скажи мне, что этот виджет не существует, если я знаю, что он существует? - PullRequest
0 голосов
/ 01 марта 2020
# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'messagerGUI.ui'
#
# Created by: PyQt5 UI code generator 5.13.0
#
# WARNING! All changes made in this file will be lost!
# ""

from PyQt5 import QtCore, QtGui, QtWidgets
import socket
import threading


class Ui_MainWindow(object):
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    header = 12
    connections = []
    ip = socket.gethostname()
    port = 1234
    connections_allowed = 3
    sock.bind((ip, port))
    sock.listen(connections_allowed)
    new_message = False

    def start(self):
        while True:
            self.conn, self.addr = self.sock.accept()
            threading.Thread(target=self.receive_data, args=[
                             self.conn], daemon=True).start()
            self.connections.append(self.conn)

    def receive_data(self, conn):
        self.reply = ""
        while True:
            try:

                message_lenth = conn.recv(self.header)
                lenth_of_message = message_lenth.decode("utf-8")

                if not message_lenth:
                    break

                elif message_lenth:
                    data = conn.recv(int(lenth_of_message))
                    self.reply = data.decode("utf-8")

                    print(self.reply)
                    self.new_message = True

                    for connection in self.connections:
                        if connection != conn:
                            connection.send(message_lenth.encode("utf-8"))
                            connection.send(self.reply.encode("utf-8"))

            except:
                break

    def packing_data_lenth(self, text):
        return len(text) * 4

    def send_data(self, data):
        try:
            for connection in self.connections:
                connection.send(
                    bytes(str(self.packing_data_lenth(data)), "utf-8"))
                connection.send(bytes(data, "utf-8"))
        except:
            pass


    def setupUi(self, MainWindow):
        threading.Thread(target=self.start, daemon=True).start()
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(499, 367)
        MainWindow.setStyleSheet("background-color: #113e4a;")
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.horizontalLayout = QtWidgets.QHBoxLayout(self.centralwidget)
        self.horizontalLayout.setContentsMargins(5, 5, 5, 5)
        self.horizontalLayout.setSpacing(5)
        self.horizontalLayout.setObjectName("horizontalLayout")

        self.info = QtWidgets.QWidget(self.centralwidget)
        sizePolicy = QtWidgets.QSizePolicy(
            QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Minimum)
        sizePolicy.setHeightForWidth(
            self.info.sizePolicy().hasHeightForWidth())
        self.info.setSizePolicy(sizePolicy)
        self.info.setMinimumSize(QtCore.QSize(178, 357))
        self.info.setStyleSheet("background-color: #429178;\n"
                                "border-radius: 2px;")
        self.info.setObjectName("info")
        self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.info)

        self.verticalLayout_3.setObjectName("verticalLayout_3")
        self.label_3 = QtWidgets.QLabel(self.info)
        self.label_3.setObjectName("label_3")
        self.verticalLayout_3.addWidget(self.label_3)
        spacerItem = QtWidgets.QSpacerItem(
            20, 317, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
        self.verticalLayout_3.addItem(spacerItem)
        self.horizontalLayout.addWidget(self.info)

        self.message_widget()

        self.chat_area = QtWidgets.QWidget(self.centralwidget)
        sizePolicy = QtWidgets.QSizePolicy(
            QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
        sizePolicy.setHeightForWidth(
            self.chat_area.sizePolicy().hasHeightForWidth())
        self.chat_area.setSizePolicy(sizePolicy)
        self.chat_area.setMinimumSize(QtCore.QSize(306, 0))
        self.chat_area.setStyleSheet("background-color: #429178;")
        self.chat_area.setObjectName("chat_area")
        self.verticalLayout = QtWidgets.QVBoxLayout(self.chat_area)
        self.verticalLayout.setContentsMargins(2, 2, 2, 2)
        self.verticalLayout.setSpacing(1)
        self.verticalLayout.setObjectName("verticalLayout")

        self.messages_area = QtWidgets.QScrollArea(self.chat_area)
        sizePolicy = QtWidgets.QSizePolicy(
            QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.MinimumExpanding)
        sizePolicy.setHeightForWidth(
            self.messages_area.sizePolicy().hasHeightForWidth())
        self.messages_area.setSizePolicy(sizePolicy)
        self.messages_area.setMinimumSize(QtCore.QSize(0, 259))
        self.messages_area.setStyleSheet("background-color: #113e4a;")
        self.messages_area.setWidgetResizable(True)
        self.messages_area.setObjectName("messages_area")

        self.scrollAreaWidgetContents = QtWidgets.QWidget()
        self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 300, 316))
        sizePolicy = QtWidgets.QSizePolicy(
            QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Minimum)
        sizePolicy.setHeightForWidth(
            self.scrollAreaWidgetContents.sizePolicy().hasHeightForWidth())
        self.scrollAreaWidgetContents.setSizePolicy(sizePolicy)
        self.scrollAreaWidgetContents.setLayoutDirection(QtCore.Qt.LeftToRight)
        self.scrollAreaWidgetContents.setObjectName("scrollAreaWidgetContents")
        self.verticalLayout_2 = QtWidgets.QVBoxLayout(
            self.scrollAreaWidgetContents)
        self.verticalLayout_2.setSizeConstraint(
            QtWidgets.QLayout.SetNoConstraint)
        self.verticalLayout_2.setSpacing(6)
        self.verticalLayout_2.setObjectName("verticalLayout_2")

        spacerItem1 = QtWidgets.QSpacerItem(
            20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.MinimumExpanding)
        self.verticalLayout_2.addItem(spacerItem1)
        self.messages_area.setWidget(self.scrollAreaWidgetContents)
        self.verticalLayout.addWidget(self.messages_area)

        self.input_area = QtWidgets.QWidget(self.chat_area)
        self.input_area.setMinimumSize(QtCore.QSize(0, 30))
        self.input_area.setObjectName("input_area")
        self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.input_area)
        self.horizontalLayout_2.setContentsMargins(1, 1, 1, 1)
        self.horizontalLayout_2.setSpacing(1)
        self.horizontalLayout_2.setObjectName("horizontalLayout_2")
        self.userInput = QtWidgets.QLineEdit(self.input_area)
        sizePolicy = QtWidgets.QSizePolicy(
            QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Minimum)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.userInput.sizePolicy().hasHeightForWidth())
        self.userInput.setSizePolicy(sizePolicy)
        self.userInput.setMinimumSize(QtCore.QSize(22, 32))
        font = QtGui.QFont()
        font.setPointSize(12)
        self.userInput.setFont(font)
        self.userInput.setStyleSheet("background-color: rgb(17, 62, 74);\n"
                                     "color: #d0e8ce;\n"
                                     "border: 0px;")
        self.userInput.setInputMethodHints(QtCore.Qt.ImhNone)
        self.userInput.setFrame(True)
        self.userInput.setDragEnabled(True)
        self.userInput.setPlaceholderText("Type a message")
        self.userInput.setObjectName("userInput")
        self.horizontalLayout_2.addWidget(self.userInput)
        self.sendButton = QtWidgets.QPushButton(self.input_area)
        sizePolicy = QtWidgets.QSizePolicy(
            QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.sendButton.sizePolicy().hasHeightForWidth())
        self.sendButton.setSizePolicy(sizePolicy)
        self.sendButton.setMinimumSize(QtCore.QSize(12, 32))
        font = QtGui.QFont()
        font.setPointSize(12)
        self.sendButton.setFont(font)
        self.sendButton.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
        self.sendButton.setMouseTracking(True)
        self.sendButton.setObjectName("sendButton")
        self.sendButton.clicked.connect(self.get_user_input)
        self.horizontalLayout_2.addWidget(self.sendButton)
        self.verticalLayout.addWidget(self.input_area)
        self.horizontalLayout.addWidget(self.chat_area)
        MainWindow.setCentralWidget(self.centralwidget)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

В этой части (функция message_widget) я получаю сообщение об ошибке:

self.widget = QtWidgets.QWidget (self.scrollAreaWidgetContents) AttributeError: у объекта 'Ui_MainWindow' нет атрибута 'scrollAreaWidgetContents '

Несмотря на то, что я сделал нечто похожее в функции get_user_input, я знаю, что код - беспорядок, но единственная часть, которая не работает, - это эта часть, сервер сокетов и клиент работают правильно, Я проверил печать текста, полученного в терминале, так что да, я хочу знать, почему я получаю эту ошибку?

    def message_widget(self):
        self.widget = QtWidgets.QWidget(self.scrollAreaWidgetContents)
        sizePolicy = QtWidgets.QSizePolicy(
            QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Minimum)
        sizePolicy.setHeightForWidth(
            self.widget.sizePolicy().hasHeightForWidth())
        self.widget.setSizePolicy(sizePolicy)
        self.widget.setMinimumSize(QtCore.QSize(158, 25))
        self.widget.setLayoutDirection(QtCore.Qt.LeftToRight)
        self.widget.setStyleSheet(
            "background-color: #d35439;\n" "border-radius: 4px;")
        self.widget.setObjectName("widget")
        self.horizontalLayout_3 = QtWidgets.QHBoxLayout(self.widget)
        self.horizontalLayout_3.setObjectName("horizontalLayout_3")

        self.label = QtWidgets.QLabel(self.widget)
        self.label.setScaledContents(True)
        self.label.setObjectName("label")
        self.label.text(self.reply)
        self.horizontalLayout_3.addWidget(self.label)
        self.verticalLayout_2.addWidget(self.widget)

    def get_user_input(self):
        self.user_msg = self.userInput.text()

        threading.Thread(target=self.send_data, args=[
                         self.user_msg], daemon=True).start()

        self.widget_2 = QtWidgets.QWidget(self.scrollAreaWidgetContents)
        sizePolicy = QtWidgets.QSizePolicy(
            QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
        sizePolicy.setHeightForWidth(
            self.widget_2.sizePolicy().hasHeightForWidth())
        self.widget_2.setSizePolicy(sizePolicy)
        self.widget_2.setMinimumSize(QtCore.QSize(182, 25))
        self.widget_2.setLayoutDirection(QtCore.Qt.RightToLeft)
        self.widget_2.setStyleSheet("background-color: rgb(236, 172, 55);\n"
                                    "border-radius: 4px;")
        self.widget_2.setObjectName("widget_2")
        self.horizontalLayout_4 = QtWidgets.QHBoxLayout(self.widget_2)
        self.horizontalLayout_4.setObjectName("horizontalLayout_4")

        self.label_2 = QtWidgets.QLabel(self.widget_2)
        self.label_2.setLayoutDirection(QtCore.Qt.RightToLeft)
        self.label_2.setAlignment(
            QtCore.Qt.AlignRight | QtCore.Qt.AlignTrailing | QtCore.Qt.AlignVCenter)
        self.label_2.setObjectName("label_2")
        self.label_2.setText(self.user_msg)
        self.horizontalLayout_4.addWidget(self.label_2)
        self.verticalLayout_2.addWidget(self.widget_2)
        self.userInput.setText("")

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "PadoMessager"))
        self.label_3.setText(_translate("MainWindow", "Server"))
        self.sendButton.setText(_translate("MainWindow", "Send"))
        self.sendButton.setShortcut(_translate("MainWindow", "Return"))


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

1 Ответ

0 голосов
/ 01 марта 2020

Вы думаете, оно существует, но когда вы вызываете message_widget(), оно еще не существует.

Фактически, вы вызываете эту функцию до этой строки. :

self.scrollAreaWidgetContents = QtWidgets.QWidget()

Итак, может работать, если вы поместите эту функцию как минимум после создания этого виджета.

К сожалению, у вашего кода есть и другие серьезные проблемы.

Самым важным является то, что вы модифицируете вывод pyui c для создания своей программы, которая крайне не рекомендуется (и сообщение WARNING на начало должно быть подсказкой).

Сценарии python, сгенерированные из файлов пользовательского интерфейса, должны НИКОГДА не редактироваться, но использоваться как импорт в ваших реальных программных файлах. Наиболее очевидная причина заключается в том, что как только вы захотите внести некоторые изменения в пользовательский интерфейс, вы окажетесь в беспорядке, пытаясь объединить новый сгенерированный код с тем, что вы уже написали.

Чтобы узнать больше об этом, прочитайте документацию о , используя Designer .

Другие проблемы в вашем коде:

  • Потоки в Qt должны использоваться с собственным QThread Qtread. насколько это возможно;
  • объекты интерфейса должны никогда никогда не быть доступны или изменены внешним потоком; для этого вам нужно использовать QThread и обмениваться данными с основным потоком Qt, используя сигналы и слоты;
  • QLabel.text() не принимает параметры, так как он используется для доступа к свойству text; чтобы установить текст метки, используйте setText();
...