コード例 #1
1
ファイル: mdi_history.py プロジェクト: lacquer/linuxcnc
class MDIHistory(QWidget, _HalWidgetBase):
    def __init__(self, parent=None):
        super(MDIHistory, self).__init__(parent)
        self.setMinimumSize(QSize(300, 200))    
        self.setWindowTitle("PyQt5 editor test example") 

        lay = QVBoxLayout()
        lay.setContentsMargins(0,0,0,0)
        self.setLayout(lay)

        self.list = QListView()
        self.list.setEditTriggers(QListView.NoEditTriggers)
        self.list.activated.connect(self.activated)
        self.list.setAlternatingRowColors(True)
        self.list.selectionChanged = self.selectionChanged
        self.model = QStandardItemModel(self.list)


        self.MDILine = MDILine()
        self.MDILine.soft_keyboard = False
        self.MDILine.line_up = self.line_up
        self.MDILine.line_down = self.line_down

        # add widgets
        lay.addWidget(self.list)
        lay.addWidget(self.MDILine)
        self.reload()

    def _hal_init(self):
        STATUS.connect('state-off', lambda w: self.setEnabled(False))
        STATUS.connect('state-estop', lambda w: self.setEnabled(False))
        STATUS.connect('interp-idle', lambda w: self.setEnabled(STATUS.machine_is_on()
                                                                and (STATUS.is_all_homed()
                                                                or INFO.NO_HOME_REQUIRED)))
        STATUS.connect('interp-run', lambda w: self.setEnabled(not STATUS.is_auto_mode()))
        STATUS.connect('all-homed', lambda w: self.setEnabled(STATUS.machine_is_on()))

    def reload(self, w=None ):
        print 'RELOAD'
        try:
            fp = os.path.expanduser(INFO.MDI_HISTORY_PATH)
            with open(fp,'r') as inputfile:
                for line in inputfile:
                    line = line.rstrip('\n')
                    item = QStandardItem(line)
                    self.model.appendRow(item)
            self.list.setModel(self.model)
            self.list.scrollToBottom()
        except Exception as e:
            print e
            LOG.error('File path is not valid: {}]n,()'.format(fp),e)

    def line_up(self):
        print 'up'

    def line_down(self):
        print 'down'

    def selectionChanged(self,old, new):
        cmd = self.getSelected()
        self.MDILine.setText(cmd)


    def getSelected(self):
        selected_indexes = self.list.selectedIndexes()
        selected_rows = [item.row() for item in selected_indexes]
        # iterates each selected row in descending order
        for selected_row in sorted(selected_rows, reverse=True):
            text = self.model.item(selected_row).text()
            return text

    def activated(self):
        cmd = self.getSelected()
        self.MDILine.setText(cmd)
        self.MDILine.submit()
        item = QStandardItem(cmd)
        self.model.appendRow(item)
        self.list.update()
    #########################################################################
    # This is how designer can interact with our widget properties.
    # designer will show the pyqtProperty properties in the editor
    # it will use the get set and reset calls to do those actions
    #########################################################################

    def set_soft_keyboard(self, data):
        self.MDILine.soft_keyboard = data
    def get_soft_keyboard(self):
        return self.MDILine.soft_keyboard
    def reset_soft_keyboard(self):
        self.MDILine.soft_keyboard = False

    # designer will show these properties in this order:
    soft_keyboard_option = pyqtProperty(bool, get_soft_keyboard, set_soft_keyboard, reset_soft_keyboard)
コード例 #2
0
class MDIHistory(QWidget, _HalWidgetBase):
    def __init__(self, parent=None):
        super(MDIHistory, self).__init__(parent)
        self.setMinimumSize(QSize(300, 200))
        self.setWindowTitle("PyQt5 editor test example")

        lay = QVBoxLayout()
        lay.setContentsMargins(0, 0, 0, 0)
        self.setLayout(lay)

        self.list = QListView()
        self.list.setEditTriggers(QListView.NoEditTriggers)
        self.list.activated.connect(self.activated)
        self.list.setAlternatingRowColors(True)
        self.list.selectionChanged = self.selectionChanged
        self.model = QStandardItemModel(self.list)

        self.MDILine = MDILine()
        self.MDILine.soft_keyboard = False
        self.MDILine.line_up = self.line_up
        self.MDILine.line_down = self.line_down

        # add widgets
        lay.addWidget(self.list)
        lay.addWidget(self.MDILine)
        self.reload()

    def _hal_init(self):
        STATUS.connect('state-off', lambda w: self.setEnabled(False))
        STATUS.connect('state-estop', lambda w: self.setEnabled(False))
        STATUS.connect(
            'interp-idle', lambda w: self.setEnabled(STATUS.machine_is_on(
            ) and (STATUS.is_all_homed() or INFO.NO_HOME_REQUIRED)))
        STATUS.connect('interp-run',
                       lambda w: self.setEnabled(not STATUS.is_auto_mode()))
        STATUS.connect('all-homed',
                       lambda w: self.setEnabled(STATUS.machine_is_on()))

    def reload(self, w=None):
        print 'RELOAD'
        try:
            fp = os.path.expanduser(INFO.MDI_HISTORY_PATH)
            with open(fp, 'r') as inputfile:
                for line in inputfile:
                    line = line.rstrip('\n')
                    item = QStandardItem(line)
                    self.model.appendRow(item)
            self.list.setModel(self.model)
            self.list.scrollToBottom()
        except Exception as e:
            print e
            LOG.error('File path is not valid: {}]n,()'.format(fp), e)

    def line_up(self):
        print 'up'

    def line_down(self):
        print 'down'

    def selectionChanged(self, old, new):
        cmd = self.getSelected()
        self.MDILine.setText(cmd)

    def getSelected(self):
        selected_indexes = self.list.selectedIndexes()
        selected_rows = [item.row() for item in selected_indexes]
        # iterates each selected row in descending order
        for selected_row in sorted(selected_rows, reverse=True):
            text = self.model.item(selected_row).text()
            return text

    def activated(self):
        cmd = self.getSelected()
        self.MDILine.setText(cmd)
        self.MDILine.submit()
        item = QStandardItem(cmd)
        self.model.appendRow(item)
        self.list.update()

    #########################################################################
    # This is how designer can interact with our widget properties.
    # designer will show the pyqtProperty properties in the editor
    # it will use the get set and reset calls to do those actions
    #########################################################################

    def set_soft_keyboard(self, data):
        self.MDILine.soft_keyboard = data

    def get_soft_keyboard(self):
        return self.MDILine.soft_keyboard

    def reset_soft_keyboard(self):
        self.MDILine.soft_keyboard = False

    # designer will show these properties in this order:
    soft_keyboard_option = pyqtProperty(bool, get_soft_keyboard,
                                        set_soft_keyboard, reset_soft_keyboard)
コード例 #3
0
class Dialog(QWidget):
    width_changed = pyqtSignal()

    def __init__(self, ip):
        super(Dialog, self).__init__()
        self.ip = ip
        self.main_layout = QVBoxLayout()
        self.header_layout = QHBoxLayout()
        self.send_layout = QHBoxLayout()
        self.send_input = QTextEdit()
        self.send_input.setPlaceholderText(variables.PLACEHOLDER_TEXT)
        self.send_input.setFont(variables.font)
        self.send_input.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        self.send_input.textChanged.connect(self.message_resize)
        self.send_input.installEventFilter(self)
        self.send_btn = PicButton(QPixmap(variables.SEND_IDLE_IMG),
                                  QPixmap(variables.SEND_HOVER_IMG),
                                  QPixmap(variables.SEND_PRESS_IMG))
        self.back_btn = PicButton(QPixmap(variables.BACK_IDLE_IMG),
                                  QPixmap(variables.BACK_HOVER_IMG),
                                  QPixmap(variables.BACK_PRESS_IMG))
        self.ip_label = QLabel(ip)
        self.ip_label.setFont(variables.font)
        self.messages = QListView()
        delegate = MessageDelegate()
        self.messages.setItemDelegate(delegate)
        self.width_changed.connect(
            lambda: delegate.sizeHintChanged.emit(QModelIndex()))
        self.model = MessageModel(ip)
        self.messages.setModel(self.model)
        self.send_btn.released.connect(self.message_to)
        self.back_btn.released.connect(self.return_to_menu)
        self.header_layout.addWidget(self.back_btn, 0,
                                     Qt.AlignVCenter | Qt.AlignLeft)
        self.header_layout.addWidget(self.ip_label, 0,
                                     Qt.AlignVCenter | Qt.AlignLeft)
        self.header_layout.addStretch()
        self.main_layout.addLayout(self.header_layout)
        self.main_layout.addWidget(self.messages)
        self.send_layout.addWidget(self.send_input)
        self.send_layout.addWidget(self.send_btn, 0, Qt.AlignBottom)
        self.main_layout.addLayout(self.send_layout)
        self.setLayout(self.main_layout)
        self.message_resize()

    def return_to_menu(self):
        variables.signals.close_dialog.emit()

    def message_to(self):
        msg = self.send_input.toPlainText()
        if not msg:
            return
        id = self.model.add_message(msg, variables.USER_ME)
        variables.nw.send_message(id, msg, self.ip)
        variables.signals.message_sent.emit(msg, self.ip)
        self.messages.scrollToBottom()
        self.send_input.clear()
        self.send_input.setFocus()

    def message_from(self, msg):
        self.model.add_message(msg, variables.USER_THEM)

    def undelivered_status(self, id):
        self.model.setUndelivered(id)

    def delivered_status(self, id):
        self.model.setUnread(id)

    def read_status(self, id):
        self.model.setRead(id)

    def message_resize(self):
        height = self.send_input.document().documentLayout().documentSize(
        ).height()
        fm = QFontMetrics(variables.font)
        space = self.send_input.document().documentMargin()
        rowNum = int(
            (height - (2 * self.send_input.document().documentMargin())) /
            fm.lineSpacing())
        if rowNum == 0:
            rowNum = 1
        if rowNum > variables.MAX_ROWS:
            rowNum = variables.MAX_ROWS
        margins = self.send_input.contentsMargins()
        height = fm.lineSpacing() * rowNum + (
            self.send_input.document().documentMargin() + self.send_input.
            frameWidth()) * 2 + margins.top() + margins.bottom()
        self.send_input.setFixedHeight(int(height))

    def eventFilter(self, widget, event):
        if event.type() == QEvent.KeyPress:
            keyEvent = QKeyEvent(event)
            if (not (keyEvent.modifiers() & Qt.ShiftModifier)) and (
                (keyEvent.key() == Qt.Key_Enter) or
                (keyEvent.key() == Qt.Key_Return)):
                self.message_to()
                return True
        return QWidget.eventFilter(self, widget, event)
コード例 #4
0
class MDIHistory(QWidget, _HalWidgetBase):
    def __init__(self, parent=None):
        super(MDIHistory, self).__init__(parent)
        self.setMinimumSize(QSize(200, 150))
        self.setWindowTitle("PyQt5 editor test example")

        lay = QVBoxLayout()
        lay.setContentsMargins(0, 0, 0, 0)
        self.setLayout(lay)

        self.list = QListView()
        self.list.setEditTriggers(QListView.NoEditTriggers)
        self.list.activated.connect(self.activated)
        self.list.setAlternatingRowColors(True)
        self.list.selectionChanged = self.selectionChanged
        self.model = QStandardItemModel(self.list)

        self.MDILine = MDILine()
        self.MDILine.soft_keyboard = False
        self.MDILine.line_up = self.line_up
        self.MDILine.line_down = self.line_down

        STATUS.connect('mdi-history-changed', self.reload)

        # add widgets
        lay.addWidget(self.list)
        lay.addWidget(self.MDILine)

        self.fp = os.path.expanduser(INFO.MDI_HISTORY_PATH)
        try:
            open(self.fp, 'r')
        except:
            open(self.fp, 'a+')
            LOG.debug('MDI History file created: {}'.format(self.fp))
        self.reload()
        self.select_row('last')

    def _hal_init(self):
        STATUS.connect('state-off', lambda w: self.setEnabled(False))
        STATUS.connect('state-estop', lambda w: self.setEnabled(False))
        STATUS.connect(
            'interp-idle', lambda w: self.setEnabled(STATUS.machine_is_on(
            ) and (STATUS.is_all_homed() or INFO.NO_HOME_REQUIRED)))
        STATUS.connect('interp-run',
                       lambda w: self.setEnabled(not STATUS.is_auto_mode()))
        STATUS.connect('all-homed',
                       lambda w: self.setEnabled(STATUS.machine_is_on()))

    def reload(self, w=None):
        self.model.clear()
        try:
            with open(self.fp, 'r') as inputfile:
                for line in inputfile:
                    line = line.rstrip('\n')
                    item = QStandardItem(line)
                    self.model.appendRow(item)
            self.list.setModel(self.model)
            self.list.scrollToBottom()
            if self.MDILine.hasFocus():
                self.select_row('last')
        except:
            LOG.debug('File path is not valid: {}'.format(fp))

    def selectionChanged(self, old, new):
        cmd = self.getSelected()
        self.MDILine.setText(cmd)
        selectionModel = self.list.selectionModel()
        if selectionModel.hasSelection():
            self.row = selectionModel.currentIndex().row()

    def getSelected(self):
        selected_indexes = self.list.selectedIndexes()
        selected_rows = [item.row() for item in selected_indexes]
        # iterates each selected row in descending order
        for selected_row in sorted(selected_rows, reverse=True):
            text = self.model.item(selected_row).text()
            return text

    def activated(self):
        cmd = self.getSelected()
        self.MDILine.setText(cmd)
        self.MDILine.submit()
        self.select_row('down')

    def run_command(self):
        self.MDILine.submit()
        self.select_row('last')

    def select_row(self, style):
        style = style.lower()
        selectionModel = self.list.selectionModel()
        parent = QModelIndex()
        self.rows = self.model.rowCount(parent) - 1
        if style == 'last':
            self.row = self.rows
            print 'last =', self.row
        elif style == 'up':
            if self.row > 0:
                self.row -= 1
            else:
                self.row = 0
        elif style == 'down':
            if self.row < self.rows:
                self.row += 1
            else:
                self.row = self.rows
        else:
            return
        top = self.model.index(self.row, 0, parent)
        bottom = self.model.index(self.row, 0, parent)
        selectionModel.setCurrentIndex(
            top, QItemSelectionModel.Select | QItemSelectionModel.Rows)
        selection = QItemSelection(top, top)
        selectionModel.clearSelection()
        selectionModel.select(selection, QItemSelectionModel.Select)

    def line_up(self):
        self.select_row('up')

    def line_down(self):
        self.select_row('down')

    #########################################################################
    # This is how designer can interact with our widget properties.
    # designer will show the pyqtProperty properties in the editor
    # it will use the get set and reset calls to do those actions
    #########################################################################

    def set_soft_keyboard(self, data):
        self.MDILine.soft_keyboard = data

    def get_soft_keyboard(self):
        return self.MDILine.soft_keyboard

    def reset_soft_keyboard(self):
        self.MDILine.soft_keyboard = False

    # designer will show these properties in this order:
    soft_keyboard_option = pyqtProperty(bool, get_soft_keyboard,
                                        set_soft_keyboard, reset_soft_keyboard)
コード例 #5
0
ファイル: mdi_history.py プロジェクト: LinuxCNC/linuxcnc
class MDIHistory(QWidget, _HalWidgetBase):
    def __init__(self, parent=None):
        super(MDIHistory, self).__init__(parent)
        self.setMinimumSize(QSize(200, 150))    
        self.setWindowTitle("PyQt5 editor test example") 

        lay = QVBoxLayout()
        lay.setContentsMargins(0,0,0,0)
        self.setLayout(lay)

        self.list = QListView()
        self.list.setEditTriggers(QListView.NoEditTriggers)
        self.list.activated.connect(self.activated)
        self.list.setAlternatingRowColors(True)
        self.list.selectionChanged = self.selectionChanged
        self.model = QStandardItemModel(self.list)

        self.MDILine = MDILine()
        self.MDILine.soft_keyboard = False
        self.MDILine.line_up = self.line_up
        self.MDILine.line_down = self.line_down

        STATUS.connect('reload-mdi-history', self.reload)

        # add widgets
        lay.addWidget(self.list)
        lay.addWidget(self.MDILine)

        self.fp = os.path.expanduser(INFO.MDI_HISTORY_PATH)
        try:
            open(self.fp, 'r')
        except:
            open(self.fp, 'a+')
            LOG.debug('MDI History file created: {}'.format(self.fp))
        self.reload()
        self.select_row('last')

    def _hal_init(self):
        STATUS.connect('state-off', lambda w: self.setEnabled(False))
        STATUS.connect('state-estop', lambda w: self.setEnabled(False))
        STATUS.connect('interp-idle', lambda w: self.setEnabled(STATUS.machine_is_on()
                                                                and (STATUS.is_all_homed()
                                                                or INFO.NO_HOME_REQUIRED)))
        STATUS.connect('interp-run', lambda w: self.setEnabled(not STATUS.is_auto_mode()))
        STATUS.connect('all-homed', lambda w: self.setEnabled(STATUS.machine_is_on()))

    def reload(self, w=None ):
        self.model.clear()
        try:
            with open(self.fp,'r') as inputfile:
                for line in inputfile:
                    line = line.rstrip('\n')
                    item = QStandardItem(line)
                    self.model.appendRow(item)
            self.list.setModel(self.model)
            self.list.scrollToBottom()
            if self.MDILine.hasFocus():
                self.select_row('last')
        except:
            LOG.debug('File path is not valid: {}'.format(fp))

    def selectionChanged(self,old, new):
        cmd = self.getSelected()
        self.MDILine.setText(cmd)
        selectionModel = self.list.selectionModel()
        if selectionModel.hasSelection():
            self.row = selectionModel.currentIndex().row()

    def getSelected(self):
        selected_indexes = self.list.selectedIndexes()
        selected_rows = [item.row() for item in selected_indexes]
        # iterates each selected row in descending order
        for selected_row in sorted(selected_rows, reverse=True):
            text = self.model.item(selected_row).text()
            return text

    def activated(self):
        cmd = self.getSelected()
        self.MDILine.setText(cmd)
        self.MDILine.submit()
        self.select_row('down')

    def select_row(self, style):
        selectionModel = self.list.selectionModel()
        parent = QModelIndex()
        self.rows = self.model.rowCount(parent) - 1
        if style == 'last':
            self.row = self.rows
        elif style == 'up':
            if self.row > 0:
                self.row -= 1
            else:
                self.row = self.rows
        elif style == 'down':
            if self.row < self.rows:
                self.row += 1
            else:
                self.row = 0
        else:
            return
        top = self.model.index(self.row, 0, parent)
        bottom = self.model.index(self.row, 0, parent)
        selectionModel.setCurrentIndex(top, QItemSelectionModel.Select | QItemSelectionModel.Rows)
        selection = QItemSelection(top, top)
        selectionModel.clearSelection()
        selectionModel.select(selection, QItemSelectionModel.Select)

    def line_up(self):
        self.select_row('up')

    def line_down(self):
        self.select_row('down')

    #########################################################################
    # This is how designer can interact with our widget properties.
    # designer will show the pyqtProperty properties in the editor
    # it will use the get set and reset calls to do those actions
    #########################################################################

    def set_soft_keyboard(self, data):
        self.MDILine.soft_keyboard = data
    def get_soft_keyboard(self):
        return self.MDILine.soft_keyboard
    def reset_soft_keyboard(self):
        self.MDILine.soft_keyboard = False

    # designer will show these properties in this order:
    soft_keyboard_option = pyqtProperty(bool, get_soft_keyboard, set_soft_keyboard, reset_soft_keyboard)
コード例 #6
0
class ConversationView(QFrame):
    """
    View

    Displays an active conversation, including  all previous messages and a text field for sending new
    messages to the recipient
    """

    def __init__(self, parent: Optional[QWidget], client: Client, peer: Peer,
                 friends_list: PeerList, conversation_list: PeerList):

        super().__init__(parent)
        self.setObjectName("conversation_view")

        self._peer = peer
        self._client = client
        self._friends_list = friends_list
        self._conversation_list = conversation_list
        self._conversation_model = self._client.conversation(self._peer)  # Model containing messages
        self._layout_manager = QVBoxLayout(self)

        # Configure message list
        self._message_list = QListView()  # View used to display conversation messages (the model)
        self._message_list.setWordWrap(True)
        self._message_list.setModel(self._conversation_model)

        # Set up custom delegate
        message_delegate = MessageItemDelegate(self._message_list)
        self._message_list.setItemDelegate(message_delegate)
        self._send_view = MessageSendView(self,
                                          self._conversation_model.peer().username() if self._conversation_model else None)
        self.setup_ui()

    def setup_ui(self):
        """
        Builds UI for display
        """

        self._layout_manager.setContentsMargins(0, 0, 0, 0)
        self._send_view.setContentsMargins(0, 0, 0, 0)

        self._message_list.setModel(self._conversation_model)  # Connect model
        self._message_list.setLayoutMode(QListView.Batched)  # Display as needed
        self._message_list.setBatchSize(10)  # Number of messages to display
        self._message_list.setFlow(QListView.TopToBottom)  # Display vertically
        self._message_list.setResizeMode(QListView.Adjust)  # Items laid out every time view is resized

        # Layout widgets and views
        # self._layout_manager.addWidget(header)
        self._layout_manager.addWidget(self._message_list, 1)
        self._layout_manager.addWidget(self._send_view)

        # Connect to signals
        self._send_view.text_edit().keyPressEvent = self.send_view_did_change
        self._message_list.verticalScrollBar().rangeChanged.connect(self.scroll_to_message)

    # Listeners

    def send_view_did_change(self, event: QKeyEvent):
        """
        As QPlainTextEdit doesn't natively support enter key response, this function prevents the user from typing the
        'enter' key and sends a message on its press instead
        :param event: QKeyEvent raised by key press
        """

        text_field = self._send_view.text_edit()

        if event.key() == Qt.Key_Return:
            message: str = text_field.toPlainText()

            if not message:  # Don't want to allow sending of empty messages
                return

            # Clear message send view
            self._send_view.text_edit().clear()

            # Create message
            chat_msg = ChatMessage(message)

            # Send over network to peer
            self._client.send_chat(self._peer, chat_msg)
        else:
            QPlainTextEdit.keyPressEvent(text_field, event)

    def peer(self):
        """
        Getter
        :return: this conversation's peer
        """
        return self._peer

    @QtCore.pyqtSlot()
    def scroll_to_message(self):
        """
        Event Listener connected to QListView's vertical scroll bar's range change

        Scrolls to a new message when view reflects a new message in the model
        """

        self._message_list.scrollToBottom()
コード例 #7
0
ファイル: client_gui2.py プロジェクト: vsurguch/client
class AppWindow(QMainWindow):
    def __init__(self, parent=None):
        QMainWindow.__init__(self, parent)
        self.setGeometry(100, 100, 550, 400)
        self.setUpMenu()
        self.setUpLayout()
        self.checkBoxConnect.stateChanged.connect(self.connect_disconnect)
        self.addButton.clicked.connect(self.add_contact)
        self.deleteButton.clicked.connect(self.delete_contact)
        self.sendButton.clicked.connect(self.send_message)
        self.contactsList.clicked.connect(self.select_contact)
        # self.messageField.drop.connect(self.add_file_to_message)

        # model -controller - view
        self.contact_list_model = StandardItemModelContacts(self)
        self.messages_list_model = StandardItemModelMessages(self)
        self.model = ClientModel(self.contact_list_model,
                                 self.messages_list_model)
        self.contactsList.setModel(self.contact_list_model)
        self.messagesList.setModel(self.messages_list_model)
        self.controller = ClientController(self.model)

        # signal-slot
        self.controller.auth_recieved.connect(self.authentification_recieved)
        self.controller.gotPersonal.connect(self.new_personal_message)

        # not connected
        self.connected = False
        # nobody selected
        self.currently_selected = ''

    def setUpMenu(self):
        fileMenu = self.menuBar().addMenu('File')
        quitAct = QAction('Quit', self)
        quitAct.triggered.connect(self.doQuit)
        fileMenu.addAction(quitAct)
        sendMenu = self.menuBar().addMenu('Send')
        sendFile = QAction('Send File', self)
        sendFile.triggered.connect(self.doSendFile)
        sendMenu.addAction(sendFile)

    def setUpLayout(self):
        hBoxLayout = QHBoxLayout()
        mainFrame = QFrame()
        mainFrame.setLayout(hBoxLayout)

        self.contact = QLineEdit()
        self.contact.setFont(QFont('Calibri', 14))
        self.contact.setPlaceholderText('Add Contact Here')
        self.contact.setMinimumHeight(30)
        self.contact.setMaximumHeight(30)

        self.addButton = QPushButton('+')
        self.addButton.setMinimumHeight(30)
        self.addButton.setMaximumHeight(30)
        self.addButton.setMinimumWidth(30)
        self.addButton.setMaximumWidth(30)

        self.deleteButton = QPushButton('-')
        self.deleteButton.setMinimumHeight(30)
        self.deleteButton.setMaximumHeight(30)
        self.deleteButton.setMinimumWidth(30)
        self.deleteButton.setMaximumWidth(30)

        self.contactsList = QListView()
        self.contactsList.setFrameShape(QFrame.Box)

        spacer = QFrame()
        spacer.setMaximumWidth(5)

        self.nameLabel = QLabel('Username')
        self.nameLabel.setMinimumHeight(30)
        self.nameLabel.setMaximumHeight(30)
        self.nameLabel.setFont(QFont('Calibri', 14))
        self.checkBoxConnect = QCheckBox()
        self.checkBoxConnect.setText('Connect')
        self.checkBoxConnect.setChecked(False)
        self.checkBoxConnect.setMaximumHeight(30)
        self.checkBoxConnect.setMinimumHeight(30)
        self.checkBoxConnect.setMaximumWidth(70)
        self.checkBoxConnect.setMinimumWidth(70)

        self.messagesList = QListView()
        self.messagesList.setIconSize(QSize(30, 30))
        self.messagesList.setFrameShape(QFrame.Box)
        self.messageField = MessageField()
        self.messageField.setMinimumHeight(50)
        self.messageField.setMaximumHeight(50)
        self.sendButton = QPushButton()
        self.sendButton.setText('>>')
        self.sendButton.setMinimumHeight(50)
        self.sendButton.setMaximumHeight(50)
        self.sendButton.setMinimumWidth(50)
        self.sendButton.setMaximumWidth(50)

        contBox = QGridLayout()
        contBox.addWidget(self.contact, 0, 0)
        contBox.addWidget(self.addButton, 0, 1)
        contBox.addWidget(self.deleteButton, 0, 2)
        contBox.addWidget(self.contactsList, 1, 0, 2, 3)
        contBox.addWidget(spacer, 0, 3, 3, 1)
        contBox.addWidget(self.nameLabel, 0, 4)
        contBox.addWidget(self.checkBoxConnect, 0, 5, 1, 2)
        contBox.addWidget(self.messagesList, 1, 4, 1, 3)
        contBox.addWidget(self.messageField, 2, 4, 1, 2)
        contBox.addWidget(self.sendButton, 2, 6)
        contBox.setColumnStretch(0, 3)
        contBox.setColumnStretch(4, 6)
        groupBoxCont = QFrame()
        groupBoxCont.setLayout(contBox)

        self.setCentralWidget(groupBoxCont)

    def doQuit(self):
        self.close()

    def doSendFile(self):
        filename = QFileDialog.getOpenFileName(self, 'Open file', '/home')[0]
        self.messageField.file = filename
        self.messageField.appendPlainText(filename)

    def connect_disconnect(self):
        self.checkBoxConnect.setEnabled(False)
        if self.checkBoxConnect.isChecked():
            self.authentification()
        else:
            self.user_disconnect()
            self.checkBoxConnect.setEnabled(True)

    # Log in  dialog
    def authentification(self):
        #read config file
        d = conf.read_conf()
        #show Authorization dialog
        auth_dialog = AuthDialog(self.model,
                                 d['username'],
                                 d['hostname'],
                                 d['port'],
                                 parent=self)
        auth_dialog.accepted.connect(self.auth_dialog_accepted)
        auth_dialog.rejected.connect(self.auth_dialog_rejected)
        auth_dialog.show()

    def auth_dialog_accepted(self):
        self.checkBoxConnect.setEnabled(True)
        self.controller.run_client()

    def auth_dialog_rejected(self):
        self.checkBoxConnect.setChecked(False)
        self.checkBoxConnect.setEnabled(True)

    @pyqtSlot(bool)
    def authentification_recieved(self, ok):
        if ok:
            self.connected = True
            self.checkBoxConnect.setText('Connected')
            self.nameLabel.setText('{}:'.format(self.model.username))
            self.model.contactlist.clear()
            self.model.personal_messages = []
            self.model.server_messages = []
            self.model.sent_messages = []
            self.model.open_db()
            self.controller.ask_contact_list()
        else:
            self.checkBoxConnect.setChecked(False)

    def user_disconnect(self):
        if self.connected:
            conf.save_conf(username=self.model.username,
                           hostname=self.model.host,
                           port=str(self.model.port))
            self.model.clear_data()
            self.controller.user_disconnect()
            self.contact.setText('')
            self.nameLabel.setText('')
            self.checkBoxConnect.setText('Connect')
            self.connected = False
            self.currently_selected = ''

    @pyqtSlot(str)
    def get_contact_list(self):
        pass

    def add_contact(self):
        name = self.contact.text()
        if name != '':
            self.controller.add_contact(name)
            self.contact.setText('')

    def delete_contact(self):
        name = self.contact.text()
        if name != '':
            self.controller.delete_contact(name)
            self.contact.setText('')

    @pyqtSlot(QMimeData)
    def add_file_to_message(self, mime):
        self.messageField.setPlainText(mime.text())

    def send_message(self):
        sel_list = self.contactsList.selectionModel().selectedIndexes()
        if len(sel_list) > 0:
            contact = self.model.contactlist.contacts[sel_list[0].row()]
            if self.messageField.file != '':
                self.controller.send_file(contact.name, self.messageField.file)
                self.messageField.file = ''
            else:
                self.controller.personal_message(
                    contact.name, self.messageField.toPlainText())
            self.messageField.clear()
            self.model.update_messages_for_contact(contact.name)
        else:
            pass

    @pyqtSlot(QModelIndex)
    def select_contact(self, modelindex):
        item = self.contact_list_model.data(modelindex, role=Qt.DisplayRole)
        contact_name = self.model.contactlist.contacts_name[modelindex.row()]
        self.contact.setText(contact_name)
        self.show_messages_for_contact(contact_name)
        self.contactsList.setCurrentIndex(modelindex)
        self.currently_selected = contact_name

    @pyqtSlot(str)
    def new_personal_message(self, sender):
        self.model.new_message_increase(sender, True)
        # sel_list = self.listViewContacts.selectionModel().selectedIndexes()
        if sender == self.currently_selected:
            self.show_messages_for_contact(self.currently_selected)

    @pyqtSlot(str)
    def show_messages_for_contact(self, contact_name):
        self.model.update_messages_for_contact(contact_name)
        self.model.new_message_increase(contact_name, False)
        self.messagesList.scrollToBottom()
コード例 #8
0
class MainWindow(QMainWindow):
    logout_signal = pyqtSignal()
    send_message_signal = pyqtSignal(str, str)
    start_chatting_signal = pyqtSignal(str)
    switch_to_add_contact = pyqtSignal()
    switch_to_del_contact = pyqtSignal()

    def __init__(self, client_name):
        super().__init__()

        self.setFixedSize(756, 574)
        self.setWindowTitle(f'Python Messenger ({client_name})')

        central_widget = QWidget()

        self.label_contacts = QLabel('Contact list:', central_widget)
        self.label_contacts.setGeometry(QRect(10, 0, 101, 16))

        self.add_contact_btn = QPushButton('Add contact', central_widget)
        self.add_contact_btn.setGeometry(QRect(10, 450, 121, 31))

        self.remove_contact_btn = QPushButton('Remove contact', central_widget)
        self.remove_contact_btn.setGeometry(QRect(140, 450, 121, 31))

        self.label_history = QLabel('Chat room:', central_widget)
        self.label_history.setGeometry(QRect(300, 0, 391, 21))

        self.text_message = QTextEdit(central_widget)
        self.text_message.setGeometry(QRect(300, 360, 441, 71))

        self.label_new_message = QLabel('Enter message here:', central_widget)
        self.label_new_message.setGeometry(QRect(300, 330, 450, 16))

        self.toolbar = self.addToolBar('Formatting')

        self.char_style_resolver = {
            'bold': self.set_text_to_bold,
            'italic': self.set_text_to_italic,
            'underline': self.set_text_to_underline,
        }
        self.font_weight = 50
        self.font_italic = False
        self.font_underline = False

        self.text_font = QFont()

        self.text_bold = QAction(QIcon('client/ui/icons/b.jpg'), 'Bold', self)
        self.text_bold.triggered.connect(lambda: self.set_char_style('bold'))

        self.text_italic = QAction(QIcon('client/ui/icons/i.jpg'), 'Italic',
                                   self)
        self.text_italic.triggered.connect(
            lambda: self.set_char_style('italic'))

        self.text_underline = QAction(QIcon('client/ui/icons/u.jpg'),
                                      'Underline', self)
        self.text_underline.triggered.connect(
            lambda: self.set_char_style('underline'))

        self.toolbar.addActions(
            [self.text_bold, self.text_italic, self.text_underline])

        self.list_contacts = QListView(central_widget)
        self.list_contacts.setGeometry(QRect(10, 20, 251, 411))
        self.contacts_model = QStandardItemModel()
        self.list_contacts.setModel(self.contacts_model)

        self.list_messages = QListView(central_widget)
        self.list_messages.setGeometry(QRect(300, 20, 441, 301))
        self.messages_model = QStandardItemModel()
        self.list_messages.setModel(self.messages_model)
        self.is_list_messages_disable = False

        self.send_btn = QPushButton('Send', central_widget)
        self.send_btn.setGeometry(QRect(610, 450, 131, 31))

        self.clear_btn = QPushButton('Clear', central_widget)
        self.clear_btn.setGeometry(QRect(460, 450, 131, 31))

        self.setCentralWidget(central_widget)

        self.menubar = QMenuBar(self)
        self.menubar.setGeometry(QRect(0, 0, 756, 21))

        self.menu = QMenu('File', self.menubar)
        self.menu_2 = QMenu('Contacts', self.menubar)

        self.setMenuBar(self.menubar)

        self.statusBar = QStatusBar(self)
        self.setStatusBar(self.statusBar)

        self.menu_exit = QAction('Exit', self)
        self.menu_logout = QAction('Logout', self)
        self.menu.addAction(self.menu_exit)
        self.menu.addAction(self.menu_logout)

        self.add_contact_menu = QAction('Add new', self)
        self.del_contact_menu = QAction('Remove some', self)
        self.menu_2.addAction(self.add_contact_menu)
        self.menu_2.addAction(self.del_contact_menu)
        self.menu_2.addSeparator()

        self.menubar.addAction(self.menu.menuAction())
        self.menubar.addAction(self.menu_2.menuAction())

        self.message = QMessageBox()

        self.menu_exit.triggered.connect(qApp.exit)
        self.menu_logout.triggered.connect(self.menu_logout_handler)
        self.send_btn.clicked.connect(self.send_btn_handler)
        self.add_contact_btn.clicked.connect(self.add_contact_btn_handler)
        self.add_contact_menu.triggered.connect(self.add_contact_btn_handler)
        self.remove_contact_btn.clicked.connect(self.del_contact_btn_handler)
        self.del_contact_menu.triggered.connect(self.del_contact_btn_handler)
        self.list_contacts.doubleClicked.connect(
            self.list_contacts_click_handler)

    def set_elements_disable_status(self, status):
        if not isinstance(status, bool):
            raise ValueError(
                f'Disable status must be bool. Got {type(status)}')

        self.send_btn.setDisabled(status)
        self.clear_btn.setDisabled(status)
        self.text_message.setDisabled(status)
        self.is_list_messages_disable = status

    def render_welcome_message(self):
        self.messages_model.clear()
        msg = QStandardItem(
            f'Doubleclick to contact in contact list for start chatting.')
        msg.setEditable(False)
        self.messages_model.appendRow(msg)

    def render_contacts(self, contacts):
        self.contacts_model.clear()

        if contacts and isinstance(contacts, list):
            for contact in contacts:
                rendered_contact = QStandardItem(contact.friend)
                rendered_contact.setEditable(False)
                self.contacts_model.appendRow(rendered_contact)

    def render_messages(self, friend, client_name, messages):
        self.messages_model.clear()

        if messages and isinstance(messages, list):
            for message in messages:
                self.render_message(friend, client_name, message)

            self.list_messages.scrollToBottom()

    def render_message(self, friend, client_name, message):
        if not self.is_list_messages_disable:
            if message.from_client in (friend, client_name):
                date = message.created.replace(microsecond=0)
                text = message.text
                from_client = message.from_client

                msg = QStandardItem(f'{date}\n{from_client}:\n{text}')
                msg.setEditable(False)

                if from_client == client_name:
                    msg.setTextAlignment(Qt.AlignRight)
                    msg.setBackground(QBrush(QColor(240, 240, 240)))

                self.messages_model.appendRow(msg)
                self.list_messages.scrollToBottom()

    def menu_logout_handler(self):
        self.logout_signal.emit()

    def send_btn_handler(self):
        message = self.text_message.toPlainText()
        to_client_name = self.list_contacts.currentIndex().data()
        if message and to_client_name:
            self.send_message_signal.emit(to_client_name, message)
            self.text_message.clear()

    def add_contact_btn_handler(self):
        self.switch_to_add_contact.emit()

    def del_contact_btn_handler(self):
        self.switch_to_del_contact.emit()

    def list_contacts_click_handler(self):
        self.messages_model.clear()
        self.set_elements_disable_status(False)
        friend = self.list_contacts.currentIndex().data()
        self.start_chatting_signal.emit(friend)

    def set_char_style(self, style):
        cursor = self.text_message.textCursor()
        char_format = QTextCharFormat()
        self.char_style_resolver[style](char_format)
        cursor.mergeCharFormat(char_format)

    def set_text_to_bold(self, char_format):
        bold_weight = 600
        thin_weight = 50

        weight = bold_weight if self.font_weight < bold_weight else thin_weight
        char_format.setFontWeight(weight)
        self.font_weight = weight

    def set_text_to_italic(self, char_format):
        char_format.setFontItalic(not self.font_italic)
        self.font_italic = not self.font_italic

    def set_text_to_underline(self, char_format):
        char_format.setFontUnderline(not self.font_underline)
        self.font_underline = not self.font_underline