如何在python pyqt5中为主窗口添加滚动功能?

huangapple go评论46阅读模式
英文:

How do I add scroll function to main window in python pyqt5?

问题

我正在尝试使用Python中的PyQt5创建一个小应用程序来学习。对于其中一个窗口,我需要在窗口中添加垂直滚动条。现在,这个窗口上有一个使用QLabel和QLineEdit制作的表格。请查看图片以了解其外观。如何在python pyqt5中为主窗口添加滚动功能?

正如您所看到的,有许多化学品,它们超出了窗口屏幕的范围。我尝试了许多方法,但不知何故没有获得结果。如果我能够获得滚动条,所有元素都会垂直排列(使用QVBoxLayout),这不是我希望元素排列的方式。

以下是我正在使用的代码:

class ChemicalWindow(QWidget):
    def __init__(self, chemicals, data):
        super().__init__()

        self.layout = QVBoxLayout()
        self.setWindowTitle("Chemicals")
        self.setMinimumSize(QSize(600, 600))
        self.setStyleSheet("background-color:#eaf4f4;")
        self.chemicals = chemicals
        self.data = data

        self.createBody()
        self.createButtons()

    def createBody(self):

        headerLabel = QLabel('Chemicals', scroll_widget)
        headerLabel.move(265, 10)
        headerLabel.resize(70, 40)
        headerLabel.setStyleSheet("color:#000;")

        tcLabel = QLabel('Tc', scroll_widget)
        tcLabel.move(200, 50)
        tcLabel.resize(60, 30)
        tcLabel.setStyleSheet("color:#000;")

        pcLabel = QLabel('Pc', scroll_widget)
        pcLabel.move(280, 50)
        pcLabel.resize(60, 30)
        pcLabel.setStyleSheet("color:#000;")

        cpLabel = QLabel('Cp', scroll_widget)
        cpLabel.move(360, 50)
        cpLabel.resize(60, 30)
        cpLabel.setStyleSheet("color:#000;")

        self.chemical_names = self.chemicals.keys()

        y_position = 90

        # 用于以字典列表形式保存化学输入变量的列表 -> {A:[chemical_a_tc,chemical_a_pc,chemical_a_cp], B:[chemical_b_tc,chemical_b_pc,...],...}
        self.chemical_inputs = dict()

        # 为化学名称创建标签
        for name in self.chemical_names:
            chemicalLabel = QLabel(name, scroll_widget)
            chemicalLabel.move(70, y_position)
            chemicalLabel.resize(75, 30)
            chemicalLabel.setStyleSheet("color:#000;")
            chemicalLabel.setToolTip(name)
            y_position += 40

            current_chemical_inputs = dict()
            for chemical_input in self.chemicals[name]:
                current_chemical_inputs[chemical_input] = QLineEdit(scroll_widget)
            self.chemical_inputs[name] = current_chemical_inputs

        position_y = 90
        for individual_chemical in self.chemical_inputs:
            position_x = 160
            for chemical_input in self.chemical_inputs[individual_chemical]:
                self.chemical_inputs[individual_chemical][chemical_input].setText(str(self.data['chemicals'][individual_chemical][chemical_input]))
                self.chemical_inputs[individual_chemical][chemical_input].move(position_x, position_y)
                self.chemical_inputs[individual_chemical][chemical_input].resize(80, 30)
                self.chemical_inputs[individual_chemical][chemical_input].setStyleSheet("color:#000;background-color:#a9d6e5;padding:2px;")
                
                position_x += 90
            position_y += 40

    def createButtons(self):
        close_button = QPushButton('Close', self)
        close_button.move(510, 550)
        close_button.resize(70, 30)
        close_button.setStyleSheet("background-color:#00509d;color:#fff;")
        close_button.clicked.connect(self.closeButton)

    def closeButton(self):
        self.close()

我做错了什么?

英文:

I'm trying to learn pyqt5 in python by creating a small application. For one of the windows, I need to add a vertical scroll bar to the window. Now, this window has a table made using QLabel and QLineEdit. Check the picture to get exactly how it looks like.如何在python pyqt5中为主窗口添加滚动功能?

As you can see there are a lot of chemicals, which goes below the window screen. I have tried numerous approaches but somehow couldn't get the result. If I am able to get the scroll, all the elements get aligned one under another (QVBoxLayout) which is not the way I want the elements to be aligned.

Here's the code I'm using

class ChemicalWindow(QWidget):
def __init__(self,chemicals,data):
super().__init__()
self.layout = QVBoxLayout()
self.setWindowTitle("Chemicals")
self.setMinimumSize(QSize(600,600))
self.setStyleSheet("background-color:#eaf4f4;")
self.chemicals = chemicals
self.data = data
self.createBody()
self.createButtons()
def createBody(self):
headerLabel = QLabel('Chemicals',scroll_widget)
headerLabel.move(265,10)
headerLabel.resize(70,40)
headerLabel.setStyleSheet("color:#000;")
tcLabel = QLabel('Tc',scroll_widget)
tcLabel.move(200,50)
tcLabel.resize(60,30)
tcLabel.setStyleSheet("color:#000;")
pcLabel = QLabel('Pc',scroll_widget)
pcLabel.move(280,50)
pcLabel.resize(60,30)
pcLabel.setStyleSheet("color:#000;")
cpLabel = QLabel('Cp',scroll_widget)
cpLabel.move(360,50)
cpLabel.resize(60,30)
cpLabel.setStyleSheet("color:#000;")
self.chemical_names = self.chemicals.keys()
y_position = 90
# List for keeping chemical inputs variables in form of dict of list -> {A:[chemical_a_tc,chemical_a_pc,chemical_a_cp],
#                                                                        B:[chemical_b_tc,chemical_b_pc,...],...}
self.chemical_inputs = dict()
# Creating labels for the chemical names
for name in self.chemical_names:
chemicalLabel = QLabel(name,scroll_widget)
chemicalLabel.move(70,y_position)
chemicalLabel.resize(75,30)
chemicalLabel.setStyleSheet("color:#000;")
chemicalLabel.setToolTip(name)
y_position += 40
current_chemical_inputs = dict()
for chemical_input in self.chemicals[name]:
current_chemical_inputs[chemical_input] = QLineEdit(scroll_widget) 
self.chemical_inputs[name] = current_chemical_inputs
position_y = 90
for individual_chemical in self.chemical_inputs:
position_x = 160
for chemical_input in self.chemical_inputs[individual_chemical]:
self.chemical_inputs[individual_chemical][chemical_input].setText(str(self.data['chemicals'][individual_chemical][chemical_input]))
self.chemical_inputs[individual_chemical][chemical_input].move(position_x,position_y)
self.chemical_inputs[individual_chemical][chemical_input].resize(80,30)
self.chemical_inputs[individual_chemical][chemical_input].setStyleSheet("color:#000;background-color:#a9d6e5;padding:2px;")
position_x += 90                
position_y += 40
def createButtons(self):
close_button = QPushButton('Close',self)
close_button.move(510,550)
close_button.resize(70,30)
close_button.setStyleSheet("background-color:#00509d;color:#fff;")
close_button.clicked.connect(self.closeButton)
def closeButton(self):
self.close()

What am I doing wrong?

答案1

得分: 1

首先,不要使用 .move() 来手动放置您的小部件,而应该使用 QLayout(例如 QHBoxLayout 或 QVBoxLayout)。这将自动排列您的标签,并可以通过调整 stretch 和添加间隔项(QSpacerItem)来进行修改。对于更复杂的布局,您可以嵌套多个框布局或使用 QGridLayout。

现在来解决滚动问题:
首先,您要创建滚动区域。将此小部件设置为中央小部件。记得将 setWidgetResizable 设置为 True

scroller = QScrollArea()
scroller.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
scroller.resize(self.width(),self.height())
scroller.setWidgetResizable(True)
self.setCentralWidget(scroller)

接下来,创建您的容器并将其添加到滚动区域中。所有的布局元素(标签、按钮等)都应放置在此容器中。

self.container = QWidget()
scroller.setWidget(self.container)

这是我创建的完整示例程序:

import sys
from PyQt5.QtWidgets import QMainWindow, QWidget, QScrollArea, QVBoxLayout, QLabel, QApplication
from PyQt5.QtCore import Qt

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.resize(1100, 800)

        scroller = QScrollArea()
        scroller.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOn)

        self.container = QWidget()
        scroller.setWidget(self.container)
        scroller.resize(self.width(),self.height())
        scroller.setWidgetResizable(True)
        self.setCentralWidget(scroller)
        
        self.holderColumn=QVBoxLayout()
    
        txtList=["apple","banana","orange","triangle","circle","square","moon","star","sun","delta"]
        objs=list()
        for i in txtList:
            tempLabel=QLabel()
            tempLabel.setText(i)
            tempLabel.setFixedSize(300,300)
            objs.append(tempLabel)
            self.holderColumn.addWidget(tempLabel)        
        self.container.setLayout(self.holderColumn)
        
app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec()
英文:

Firstly, instead of using .move() to manually place your widgets, you should be using a QLayout (ex. QHBoxLayout or QVBoxLayout). This will automatically space your labels, and you can modify it by adjusting stretch and adding spacers (QSpacerItem). For more complex layouts, you can either nest multiple box layouts, or use a QGridLayout.

Now to address the scrolling:
First, you want to create your scroll area. Make this widget the central widget. Remember to set setWidgetResizable to True.

scroller = QScrollArea()
scroller.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
scroller.resize(self.width(),self.height())
scroller.setWidgetResizable(True)
self.setCentralWidget(scroller)

Next, create your container and add it to the scroll area. All your layout elements (labels, buttons, etc.) should be placed in this container.

self.container = QWidget()
scroller.setWidget(self.container)

Here's the full sample program I created:

import sys
from PyQt5.QtWidgets import QMainWindow, QWidget, QScrollArea, QVBoxLayout, QLabel, QApplication
from PyQt5.QtCore import Qt

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.resize(1100, 800)

        scroller = QScrollArea()
        scroller.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOn)

        self.container = QWidget()
        scroller.setWidget(self.container)
        scroller.resize(self.width(),self.height())
        scroller.setWidgetResizable(True)
        self.setCentralWidget(scroller)
        
        self.holderColumn=QVBoxLayout()
    
        txtList=["apple","banana","orange","triangle","circle","square","moon","star","sun","delta"]
        objs=list()
        for i in txtList:
            tempLabel=QLabel()
            tempLabel.setText(i)
            tempLabel.setFixedSize(300,300)
            objs.append(tempLabel)
            self.holderColumn.addWidget(tempLabel)        
        self.container.setLayout(self.holderColumn)
        
app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec()

huangapple
  • 本文由 发表于 2023年2月7日 01:05:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/75364405.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定