【问题标题】:PyQt unable to add tableWIdget to existing applicationPyQt 无法将 tableWIdget 添加到现有应用程序
【发布时间】:2019-08-30 12:21:26
【问题描述】:

我有一个想要添加表格小部件的现有应用程序。目前它看起来像这样:

我正在尝试在 tutorial 之后添加一个 PyQt5 表。

我的代码如下:

class App(QMainWindow):

def __init__(self):
    super().__init__()
    self.player = QMediaPlayer()        # QMediaPlayer class allows the playing of a media source.
    self.playlist = QMediaPlaylist()    # QMediaPlaylist class provides a list of media content to play.
    self.title = 'PyTunes'
    self.left = 300
    self.top = 300
    self.width = 300
    self.height = 150
    self.color = 0  # 0- toggle to dark 1- toggle to light
    self.userAction = -1  # 0- stopped, 1- playing 2-paused
    self.setup_UI()

def setup_UI(self):
    # Add file menu
    menubar = self.menuBar()
    filemenu = menubar.addMenu('File')
    windowmenu = menubar.addMenu('Window')

    help_act = QAction('Open Help', self)
    folder_act = QAction('Open Folder', self)
    theme_act = QAction('Toggle light/dark theme', self)

    folder_act.setShortcut('Ctrl+D')
    help_act.setShortcut('Ctrl+H')
    theme_act.setShortcut('Ctrl+T')

    filemenu.addAction(folder_act)
    filemenu.addAction(help_act)
    windowmenu.addAction(theme_act)

    help_act.triggered.connect(self.open_help)
    folder_act.triggered.connect(self.add_files)
    theme_act.triggered.connect(self.toggle_colors)

    self.add_controls()
    self.createTable()

    self.setWindowTitle(self.title)
    self.setGeometry(self.left, self.top, self.width, self.height)
    self.toggle_colors()
    self.show()

def add_controls(self):
    wid = QWidget(self)
    self.setCentralWidget(wid)

    # Add song controls
    volumeslider = QSlider(Qt.Horizontal, self)
    volumeslider.setFocusPolicy(Qt.NoFocus)
    volumeslider.valueChanged[int].connect(self.change_volume)
    volumeslider.setValue(100)

    play_btn = QPushButton('Play')  # play button
    pause_btn = QPushButton('Pause')  # pause button
    stop_btn = QPushButton('Stop')  # stop button

    # Add playlist controls
    prev_btn = QPushButton('Prev')
    shuffle_btn = QPushButton('Shuffle')
    next_btn = QPushButton('Next')
    sort_btn = QPushButton('Sort')
    search_btn = QPushButton('Search')
    remove_btn = QPushButton('Remove')

    # Add button layouts
    control_area = QVBoxLayout()  # centralWidget
    controls = QHBoxLayout()
    playlist_ctrl_layout = QHBoxLayout()
    playlist_func = QHBoxLayout()

    # Add buttons to song controls layout
    controls.addWidget(play_btn)
    controls.addWidget(pause_btn)
    controls.addWidget(stop_btn)

    # Add buttons to playlist controls layout
    playlist_ctrl_layout.addWidget(prev_btn)
    playlist_ctrl_layout.addWidget(shuffle_btn)
    playlist_ctrl_layout.addWidget(next_btn)

    playlist_func.addWidget(sort_btn)
    playlist_func.addWidget(search_btn)
    playlist_func.addWidget(remove_btn)

    # Add to vertical layout
    control_area.addLayout(controls)
    control_area.addLayout(playlist_ctrl_layout)
    control_area.addWidget(volumeslider)
    control_area.addLayout(playlist_func)

    # control_area.addWidget(QTableWidget)   
    # control_area.addWidget(self.tableWidget)

    wid.setLayout(control_area)

    # Connect each signal to their appropriate function
    play_btn.clicked.connect(self.play_handler)
    pause_btn.clicked.connect(self.pause_handler)
    stop_btn.clicked.connect(self.stop_handler)

    prev_btn.clicked.connect(self.prev_song)
    shuffle_btn.clicked.connect(self.shuffle_list)
    next_btn.clicked.connect(self.next_song)

    sort_btn.clicked.connect(self.sort_handler)
    search_btn.clicked.connect(self.search_handler)
    remove_btn.clicked.connect(self.remove_handler)

    self.statusBar()
    # Signal emitted when current media changes. Call song_changed
    self.playlist.currentMediaChanged.connect(self.song_changed)

def createTable(self):
    # Create table
    self.tableWidget = QTableWidget()
    self.tableWidget.setRowCount(4)
    self.tableWidget.setColumnCount(2)
    self.tableWidget.setItem(0, 0, QTableWidgetItem("Cell (1,1)"))
    self.tableWidget.setItem(0, 1, QTableWidgetItem("Cell (1,2)"))
    self.tableWidget.setItem(1, 0, QTableWidgetItem("Cell (2,1)"))
    self.tableWidget.setItem(1, 1, QTableWidgetItem("Cell (2,2)"))
    self.tableWidget.setItem(2, 0, QTableWidgetItem("Cell (3,1)"))
    self.tableWidget.setItem(2, 1, QTableWidgetItem("Cell (3,2)"))
    self.tableWidget.setItem(3, 0, QTableWidgetItem("Cell (4,1)"))
    self.tableWidget.setItem(3, 1, QTableWidgetItem("Cell (4,2)"))
    self.tableWidget.move(0, 0)

    # table selection change
    self.tableWidget.doubleClicked.connect(self.on_click)

@pyqtSlot()
def on_click(self):
    print("\n")
    for currentQTableWidgetItem in self.tableWidget.selectedItems():
        print(currentQTableWidgetItem.row(), currentQTableWidgetItem.column(), currentQTableWidgetItem.text())

我在 add_controls() 中添加了盒子布局,现在我正在尝试将表格添加到盒子布局中。

我试过了:control_area.addWidget(QTableWidget) 但这会返回错误:

control_area.addWidget(QTableWidget)

TypeError: addWidget(self, QWidget, stretch: int = 0, alignment: Union[Qt.Alignment, Qt.AlignmentFlag] = Qt.Alignment()): argument 1 has unexpected type 'sip.wrappertype'

我也试过:control_area.addWidget(self.tableWidget) 但这会返回错误:

control_area.addWidget(self.tableWidget) AttributeError:“App”对象没有属性“tableWidget”

关于我做错了什么以及如何纠正的任何建议?提前致谢

【问题讨论】:

  • 你试过在control_area.addWidget(self.tableWidget)之前打电话给self.createTable()吗?

标签: python-3.x pyqt5


【解决方案1】:

试试看:

import sys
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtMultimedia import QMediaPlayer, QMediaPlaylist

class App(QMainWindow):

    def __init__(self):
        super().__init__()
        self.player   = QMediaPlayer()     # QMediaPlayer class allows the playing of a media source.
        self.playlist = QMediaPlaylist()   # QMediaPlaylist class provides a list of media content to play.
        self.title    = 'PyTunes'
        self.left   = 300
        self.top    = 300
        self.width  = 300
        self.height = 150
        self.color  = 0       # 0- toggle to dark 1- toggle to light
        self.userAction = -1  # 0- stopped, 1- playing 2-paused

        self.setup_UI()

    def setup_UI(self):
        # Add file menu
        menubar    = self.menuBar()
        filemenu   = menubar.addMenu('File')
        windowmenu = menubar.addMenu('Window')

        help_act   = QAction('Open Help', self)
        folder_act = QAction('Open Folder', self)
        theme_act  = QAction('Toggle light/dark theme', self)

        folder_act.setShortcut('Ctrl+D')
        help_act.setShortcut(  'Ctrl+H')
        theme_act.setShortcut( 'Ctrl+T')

        filemenu.addAction(folder_act)
        filemenu.addAction(help_act)
        windowmenu.addAction(theme_act)

#        help_act.triggered.connect(  self.open_help)
#        folder_act.triggered.connect(self.add_files)
#        theme_act.triggered.connect( self.toggle_colors)

        self.add_controls()

        self.createTable()

        self.control_area.addWidget(self.tableWidget)                  # <===============

        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)
#?        self.toggle_colors()
        self.show()

    def add_controls(self):
        wid = QWidget(self)
        self.setCentralWidget(wid)

        # Add song controls
        volumeslider = QSlider(Qt.Horizontal, self)
        volumeslider.setFocusPolicy(Qt.NoFocus)
#        volumeslider.valueChanged[int].connect(self.change_volume)
        volumeslider.setValue(100)

        play_btn  = QPushButton('Play')  # play button
        pause_btn = QPushButton('Pause')  # pause button
        stop_btn  = QPushButton('Stop')  # stop button

        # Add playlist controls
        prev_btn    = QPushButton('Prev')
        shuffle_btn = QPushButton('Shuffle')
        next_btn    = QPushButton('Next')
        sort_btn    = QPushButton('Sort')
        search_btn  = QPushButton('Search')
        remove_btn  = QPushButton('Remove')

        # Add button layouts
        self.control_area = QVBoxLayout()                    # + self.            
        controls     = QHBoxLayout()
        playlist_ctrl_layout = QHBoxLayout()
        playlist_func = QHBoxLayout()

        # Add buttons to song controls layout
        controls.addWidget(play_btn)
        controls.addWidget(pause_btn)
        controls.addWidget(stop_btn)

        # Add buttons to playlist controls layout
        playlist_ctrl_layout.addWidget(prev_btn)
        playlist_ctrl_layout.addWidget(shuffle_btn)
        playlist_ctrl_layout.addWidget(next_btn)

        playlist_func.addWidget(sort_btn)
        playlist_func.addWidget(search_btn)
        playlist_func.addWidget(remove_btn)

        # Add to vertical layout
        self.control_area.addLayout(controls)                # + self. 
        self.control_area.addLayout(playlist_ctrl_layout)    # + self. 
        self.control_area.addWidget(volumeslider)            # + self. 
        self.control_area.addLayout(playlist_func)           # + self. 

        # control_area.addWidget(QTableWidget)   
        # control_area.addWidget(self.tableWidget)

        wid.setLayout(self.control_area)                     # + self. 

        # Connect each signal to their appropriate function
#        play_btn.clicked.connect(self.play_handler)
#        pause_btn.clicked.connect(self.pause_handler)
#        stop_btn.clicked.connect(self.stop_handler)

#        prev_btn.clicked.connect(self.prev_song)
#        shuffle_btn.clicked.connect(self.shuffle_list)
#        next_btn.clicked.connect(self.next_song)

#        sort_btn.clicked.connect(self.sort_handler)
#        search_btn.clicked.connect(self.search_handler)
#        remove_btn.clicked.connect(self.remove_handler)

        self.statusBar()
        # Signal emitted when current media changes. Call song_changed
#        self.playlist.currentMediaChanged.connect(self.song_changed)

    def createTable(self):
        # Create table
        self.tableWidget = QTableWidget()
        self.tableWidget.setRowCount(4)
        self.tableWidget.setColumnCount(2)
        self.tableWidget.setItem(0, 0, QTableWidgetItem("Cell (1,1)"))
        self.tableWidget.setItem(0, 1, QTableWidgetItem("Cell (1,2)"))
        self.tableWidget.setItem(1, 0, QTableWidgetItem("Cell (2,1)"))
        self.tableWidget.setItem(1, 1, QTableWidgetItem("Cell (2,2)"))
        self.tableWidget.setItem(2, 0, QTableWidgetItem("Cell (3,1)"))
        self.tableWidget.setItem(2, 1, QTableWidgetItem("Cell (3,2)"))
        self.tableWidget.setItem(3, 0, QTableWidgetItem("Cell (4,1)"))
        self.tableWidget.setItem(3, 1, QTableWidgetItem("Cell (4,2)"))
        self.tableWidget.move(0, 0)

        # table selection change
        self.tableWidget.doubleClicked.connect(self.on_click)

    @pyqtSlot()
    def on_click(self):
        print("\n")
        for currentQTableWidgetItem in self.tableWidget.selectedItems():
            print(currentQTableWidgetItem.row(), 
                  currentQTableWidgetItem.column(), 
                  currentQTableWidgetItem.text())

if __name__ == '__main__':
    app = QApplication(sys.argv)
    main = App()
    main.show()
    sys.exit(app.exec_())        

【讨论】:

    【解决方案2】:

    已解决,问题出在这里:

    self.add_controls()
    self.createTable()
    

    因为我在创建表之前调用了add_controls(),结果是:

    “App”对象没有属性“tableWidget”

    【讨论】:

    • 没错,错误信息指出尚未创建表实例。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-07-25
    • 2012-08-09
    • 2012-01-27
    • 1970-01-01
    • 1970-01-01
    • 2016-06-25
    • 2014-11-26
    相关资源
    最近更新 更多