PyQt5, adding text to tabs doesn't work

蹲街弑〆低调 提交于 2020-01-05 23:25:40

问题


I am making an IDE in python and I've had some trouble adding text to my tabs.

Adding the title works but adding the text inside of it doesn't.

Here is my code:

import sys
import sys
from subprocess import PIPE, Popen
import json
from pyautogui import hotkey
from PyQt5 import QtGui, QtPrintSupport
from PyQt5.QtCore import QRect, QRegExp, Qt
from PyQt5.QtGui import (QColor, QFont, QPainter,
                         QSyntaxHighlighter, QTextCharFormat, QTextCursor)
from PyQt5.QtWidgets import (QAction, QApplication, QDialog, QFileDialog, QPushButton,
                             QHBoxLayout, QInputDialog, QMainWindow,
                             QMessageBox, QPlainTextEdit, QVBoxLayout, QWidget, QTabWidget,
                             qApp, QMenuBar, QStatusBar)

lineBarColor = QColor(53, 53, 53)
lineHighlightColor = QColor('#00FF04')


class NumberBar(QWidget):
    def __init__(self, parent=None):
        super().__init__()
        self.editor = parent
        layout = QVBoxLayout()
        self.setLayout(layout)
        self.editor.blockCountChanged.connect(self.update_width)
        self.editor.updateRequest.connect(self.update_on_scroll)
        self.update_width('1')

    def mousePressEvent(self, QMouseEvent):
        print("class NumberBar(QWidget):mousePressEvent")

    def update_on_scroll(self, rect, scroll):
        if self.isVisible():
            if scroll:
                self.scroll(0, scroll)
            else:
                self.update()

    def update_width(self, string):
        width = self.fontMetrics().width(str(string)) + 10
        print("update_width:width:" + str(width))
        if self.width() != width:
            self.setFixedWidth(width)

    def paintEvent(self, event):
        if self.isVisible():
            block = self.editor.firstVisibleBlock()
            height = self.fontMetrics().height()
            number = block.blockNumber()
            painter = QPainter(self)
            painter.fillRect(event.rect(), lineBarColor)
            painter.drawRect(0, 0, event.rect().width() - 1, event.rect().height() - 1)
            font = painter.font()

            current_block = self.editor.textCursor().block().blockNumber() + 1

            while block.isValid():
                block_geometry = self.editor.blockBoundingGeometry(block)
                offset = self.editor.contentOffset()
                block_top = block_geometry.translated(offset).top()
                number += 1

                rect = QRect(0, block_top, self.width() - 5, height)

                if number == current_block:
                    font.setBold(True)
                else:
                    font.setBold(False)

                painter.setFont(font)
                painter.drawText(rect, Qt.AlignRight, '%i' % number)

                if block_top > event.rect().bottom():
                    break

                block = block.next()

            painter.end()


class Content(QWidget):
    def __init__(self, text):
        super(Content, self).__init__()
        self.editor = QPlainTextEdit()
        # Create a layout for the line numbers

        self.hbox = QHBoxLayout()
        self.setLayout(self.hbox)
        self.numbers = NumberBar(self.editor)
        self.hbox.addWidget(self.numbers)
        self.hbox.addWidget(self.editor)


class MyTableWidget(QWidget):

    def __init__(self, parent):
        super(QWidget, self).__init__(parent)
        self.layout = QVBoxLayout(self)
        self.editor = QPlainTextEdit()
        # Initialize tab screen
        self.tabs = QTabWidget()
        self.tabs.resize(300, 200)

        # Add tabs
        self.tabs.setTabsClosable(True)
        self.tabs.tabCloseRequested.connect(self.closeTab)

        # Add tabs to widget
        self.layout.addWidget(self.tabs)
        self.setLayout(self.layout)

    def closeTab(self, index):
        tab = self.tabs.widget(index)
        tab.deleteLater()
        self.tabs.removeTab(index)

    def addtab(self, content, fileName):
        self.tabs.addTab(Content(str(content)), str(fileName))


class Main(QMainWindow):
    def __init__(self, parent=None):
        super(Main, self).__init__(parent)
        self.open()

        self.tabs = MyTableWidget(self)
        #self.tabs.addtab("nga", "sa")

        self.setCentralWidget(self.tabs)
        self.initUI()
        self.show()

    def initUI(self):
        self.statusBar()
        menu = self.menuBar()
        fileMenu = menu.addMenu('File')
        fileMenu.addAction(self.openAct)

        self.resize(800, 600)

    def closeTab(self, index):
        tab = self.tabs.widget(index)
        tab.deleteLater()
        self.tabs.removeTab(index)

    def buttonClicked(self):
        self.tabs.addTab(Content("smalltext2"), "sadsad")

    def open(self):
        self.openAct = QAction('Open...', self)
        self.openAct.setShortcut('Ctrl+O')
        self.openAct.setStatusTip('Open a file')
        self.is_opened = False
        self.openAct.triggered.connect(self.openFile)

    def openFile(self):
        options = QFileDialog.Options()
        self.files, _ = QFileDialog.getOpenFileNames(
            self, 'Open a file', '',
            'All Files (*);;Python Files (*.py);;Text Files (*.txt)',
            options=options
        )

        self.files = self.files[0]
        if self.files:
            with open(self.files, 'r+') as file_o:
                print(self.files)
                text = file_o.read()
                text_widget = QPlainTextEdit(self.tabs)
                text_widget.setPlainText(text)
                self.tabs.addtab(text_widget, self.files[0])
                print(text)


if __name__ == '__main__':
    with open("../config.json", "r") as jsonFile:
        read = jsonFile.read()
        data = json.loads(read)
        app = QApplication(sys.argv)
        app.setStyle('Fusion')
        palette = QtGui.QPalette()
        palette.setColor(QtGui.QPalette.Window, QColor(data["editor"][0]["windowColor"]))
        palette.setColor(QtGui.QPalette.WindowText, QColor(data["editor"][0]["windowText"]))
        palette.setColor(QtGui.QPalette.Base, QColor(data["editor"][0]["editorColor"]))
        palette.setColor(QtGui.QPalette.AlternateBase, QColor(data["editor"][0]["alternateBase"]))
        palette.setColor(QtGui.QPalette.ToolTipBase, QColor(data["editor"][0]["ToolTipBase"]))
        palette.setColor(QtGui.QPalette.ToolTipText, QColor(data["editor"][0]["ToolTipText"]))
        palette.setColor(QtGui.QPalette.Text, QColor(data["editor"][0]["editorText"]))
        palette.setColor(QtGui.QPalette.Button, QColor(data["editor"][0]["buttonColor"]))
        palette.setColor(QtGui.QPalette.ButtonText, QColor(data["editor"][0]["buttonTextColor"]))
        palette.setColor(QtGui.QPalette.Highlight, QColor(data["editor"][0]["HighlightColor"]).lighter())
        palette.setColor(QtGui.QPalette.HighlightedText, QColor(data["editor"][0]["HighlightedTextColor"]))
        app.setPalette(palette)
        ex = Main()
        sys.exit(app.exec_())

On the line 171 I'm trying to add a tab with the contents of the file I opened self.tabs.addtab(text_widget, self.files[0]).

It does create the tab with the name self.files[0] but the content isn't inside of there.


回答1:


The problem is really simple, you are creating many QPlainTextEdits unnecessarily, for example there is a QPlainTextEdit in openFile() method that you pass to the method addtab(), but if you check the method addtab() MyTableWidget requires a string and not the QPlainTextEdit, There is another QPlainTextEdit in MyTableWidget unnecessarily.

Eliminating the unnecessary elements we obtain the following:

import sys

from PyQt5.QtCore import Qt, QRect
from PyQt5.QtGui import QColor, QPainter
from PyQt5.QtWidgets import QApplication, QWidget, QMainWindow, QAction, \
    QVBoxLayout, QTabWidget, QFileDialog, QPlainTextEdit, QHBoxLayout


lineBarColor = QColor(53, 53, 53)
lineHighlightColor = QColor('#00FF04')


class NumberBar(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.editor = parent
        layout = QVBoxLayout(self)
        self.editor.blockCountChanged.connect(self.update_width)
        self.editor.updateRequest.connect(self.update_on_scroll)
        self.update_width('1')

    def mousePressEvent(self, QMouseEvent):
        print("class NumberBar(QWidget):mousePressEvent")

    def update_on_scroll(self, rect, scroll):
        if self.isVisible():
            if scroll:
                self.scroll(0, scroll)
            else:
                self.update()

    def update_width(self, string):
        width = self.fontMetrics().width(str(string)) + 10
        print("update_width:width:" + str(width))
        if self.width() != width:
            self.setFixedWidth(width)

    def paintEvent(self, event):
        if self.isVisible():
            block = self.editor.firstVisibleBlock()
            height = self.fontMetrics().height()
            number = block.blockNumber()
            painter = QPainter(self)
            painter.fillRect(event.rect(), lineBarColor)
            painter.drawRect(0, 0, event.rect().width() - 1, event.rect().height() - 1)
            font = painter.font()

            current_block = self.editor.textCursor().block().blockNumber() + 1

            while block.isValid():
                block_geometry = self.editor.blockBoundingGeometry(block)
                offset = self.editor.contentOffset()
                block_top = block_geometry.translated(offset).top()
                number += 1

                rect = QRect(0, block_top, self.width() - 5, height)

                if number == current_block:
                    font.setBold(True)
                else:
                    font.setBold(False)

                painter.setFont(font)
                painter.drawText(rect, Qt.AlignRight, '%i' % number)

                if block_top > event.rect().bottom():
                    break

                block = block.next()

            painter.end()


class Content(QWidget):
    def __init__(self, text):
        super(Content, self).__init__()
        self.editor = QPlainTextEdit()
        self.editor.setPlainText(text)
        # Create a layout for the line numbers

        self.hbox = QHBoxLayout(self)
        self.numbers = NumberBar(self.editor)
        self.hbox.addWidget(self.numbers)
        self.hbox.addWidget(self.editor)


class MyTableWidget(QWidget):

    def __init__(self, parent=None):
        super(QWidget, self).__init__(parent)
        self.layout = QVBoxLayout(self)
        # Initialize tab screen
        self.tabs = QTabWidget()
        self.tabs.resize(300, 200)

        # Add tabs
        self.tabs.setTabsClosable(True)
        self.tabs.tabCloseRequested.connect(self.closeTab)

        # Add tabs to widget
        self.layout.addWidget(self.tabs)
        self.setLayout(self.layout)

    def closeTab(self, index):
        tab = self.tabs.widget(index)
        tab.deleteLater()
        self.tabs.removeTab(index)

    def addtab(self, content, fileName):
        self.tabs.addTab(Content(str(content)), str(fileName))


class Main(QMainWindow):
    def __init__(self, parent=None):
        super(Main, self).__init__(parent)
        self.open()

        self.tabs = MyTableWidget()
        #self.tabs.addtab("nga", "sa")

        self.setCentralWidget(self.tabs)
        self.initUI()
        self.show()

    def initUI(self):
        self.statusBar()
        menu = self.menuBar()
        fileMenu = menu.addMenu('File')
        fileMenu.addAction(self.openAct)

        self.resize(800, 600)

    def closeTab(self, index):
        tab = self.tabs.widget(index)
        tab.deleteLater()
        self.tabs.removeTab(index)

    def buttonClicked(self):
        self.tabs.addTab(Content("smalltext2"), "sadsad")

    def open(self):
        self.openAct = QAction('Open...', self)
        self.openAct.setShortcut('Ctrl+O')
        self.openAct.setStatusTip('Open a file')
        self.is_opened = False
        self.openAct.triggered.connect(self.openFile)

    def openFile(self):
        options = QFileDialog.Options()
        filenames, _ = QFileDialog.getOpenFileNames(
            self, 'Open a file', '',
            'All Files (*);;Python Files (*.py);;Text Files (*.txt)',
            options=options
        )
        if filenames:
            for filename in filenames:
                with open(filename, 'r+') as file_o:
                    text = file_o.read()
                    self.tabs.addtab(text, filename)


if __name__ == '__main__':

    app = QApplication(sys.argv)
    ex = Main()
    sys.exit(app.exec_())


来源:https://stackoverflow.com/questions/51114563/pyqt5-adding-text-to-tabs-doesnt-work

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!