如何在一个主窗口中有两个小部件 [英] How to have two widgets in one Main window
问题描述
我整个上午都在努力解决这个问题.所以我有一个 PyQt 主窗口,我想在其中显示两个小部件.在第一个小部件中列出了文章(到目前为止有效).当我点击它们直到现在 QMessageBox 正在打开时,但我想要那个第二个小部件正在打开,我可以在其中阅读 RSS 源.但这是行不通的.请参阅下面的代码:
class ArticleWidgets(QWidget):def __init__(self, *args):super().__init__(*args)self.setGeometry(610, 610, 600, 600)self.initUi()定义 initUi(self):self.box = QHBoxLayout(self)def show(self, feed=None):self.title = QLabel()self.summary = QLabel()self.link = QLabel()如果饲料:self.title.setText(feed[0])self.summary.setText(feed[1])self.link.setText(feed[2])self.box.addWidget(self.title)self.box.addWidget(self.summary)self.box.addWidget(self.link)self.setLayout(self.box)类 TitleWidgets(QWidget):def __init__(self, *args):super().__init__(*args)self.setGeometry(10, 10, 600, 600)self.initUi()定义 initUi(self):vbox = QHBoxLayout(self)self.titleList = QListWidget()self.titleList.itemDoubleClicked.connect(self.onClicked)self.titleList.setGeometry(0, 0, 400, 400)self.news = ANFFeed()对于 self.news.all_feeds 中的项目:self.titleList.addItem(item[0])vbox.addWidget(self.titleList)def onClicked(self, item):feeds = self.news.all_feeds编号 = 0对于范围内的元素(len(feeds)):如果 feeds[elem][0] == item.text():id = 元素摘要 = feeds[id][1] + '\n\n'链接 = feeds[id][2]如果提要和 ID:#ANFApp(self).show_articles(feeds[id])显示 = ANFApp()show.show_articles(feed=feeds[id])QMessageBox.information(self, 'Details', summary + link)类 ANFApp(QMainWindow):def __init__(self, *args):super().__init__(*args)self.setWindowState(Qt.WindowMaximized)self.setWindowIcon(QIcon('anf.png'))self.setAutoFillBackground(True)self.anfInit()自我展示()def anfInit(self):self.setWindowTitle('ANF RSS 阅读器')TitleWidgets(self)#article_box = ArticleWidgets(self)exitBtn = QPushButton(self)exitBtn.setGeometry(600, 600, 100, 50)exitBtn.setText('退出')exitBtn.setStyleSheet("background-color: red")exitBtn.clicked.connect(self.exit)def show_articles(self, feed=None):存在 = 文章小部件()present.show(饲料)定义退出(自我):QCoreApplication.instance().quit()
使用 Pyqtgraph 的 Docks 和 QTextBrowser 的解决方案
这是一个试图重现你的草图的代码.我使用了 Pyqtgraph
模块(此处的文档:
如果您在两个小部件之间传递鼠标,您将看到鼠标图标会发生变化,您可以在运行时重新调整两个小部件的大小.
最后的话
这是另一种方法,更具互动性";比我之前的答案更美观.正如您所说,使用 QSplitter
也可以.
I am trying the whole morning already to fix that. So I have a PyQt Main Window where I want to display two widgets. In the first widget there are articles listed (which works so far). When I click on them until now a QMessageBox is opening, but I want that a second widget is opening where I can read the RSS Feed. But this is not working. See Code below:
class ArticleWidgets(QWidget):
def __init__(self, *args):
super().__init__(*args)
self.setGeometry(610, 610, 600, 600)
self.initUi()
def initUi(self):
self.box = QHBoxLayout(self)
def show(self, feed=None):
self.title = QLabel()
self.summary = QLabel()
self.link = QLabel()
if feed:
self.title.setText(feed[0])
self.summary.setText(feed[1])
self.link.setText(feed[2])
self.box.addWidget(self.title)
self.box.addWidget(self.summary)
self.box.addWidget(self.link)
self.setLayout(self.box)
class TitleWidgets(QWidget):
def __init__(self, *args):
super().__init__(*args)
self.setGeometry(10, 10, 600, 600)
self.initUi()
def initUi(self):
vbox = QHBoxLayout(self)
self.titleList = QListWidget()
self.titleList.itemDoubleClicked.connect(self.onClicked)
self.titleList.setGeometry(0, 0, 400, 400)
self.news = ANFFeed()
for item in self.news.all_feeds:
self.titleList.addItem(item[0])
vbox.addWidget(self.titleList)
def onClicked(self, item):
feeds = self.news.all_feeds
id = 0
for elem in range(len(feeds)):
if feeds[elem][0] == item.text():
id = elem
summary = feeds[id][1] + '\n\n'
link = feeds[id][2]
if feeds and id:
#ANFApp(self).show_articles(feeds[id])
show = ANFApp()
show.show_articles(feed=feeds[id])
QMessageBox.information(self, 'Details', summary + link)
class ANFApp(QMainWindow):
def __init__(self, *args):
super().__init__(*args)
self.setWindowState(Qt.WindowMaximized)
self.setWindowIcon(QIcon('anf.png'))
self.setAutoFillBackground(True)
self.anfInit()
self.show()
def anfInit(self):
self.setWindowTitle('ANF RSS Reader')
TitleWidgets(self)
#article_box = ArticleWidgets(self)
exitBtn = QPushButton(self)
exitBtn.setGeometry(600, 600, 100, 50)
exitBtn.setText('Exit')
exitBtn.setStyleSheet("background-color: red")
exitBtn.clicked.connect(self.exit)
def show_articles(self, feed=None):
present = ArticleWidgets()
present.show(feed)
def exit(self):
QCoreApplication.instance().quit()
Solution using Pyqtgraph's Docks and QTextBrowser
Here is a code trying to reproduce your sketch. I used the Pyqtgraph
module (Documentation here: Pyqtgraph's Documentation and Pyqtgraph's Web Page) because its Dock
widget is easier to use and implement from my perspective.
You must install the pyqtgraph
module before trying this code:
import sys
from PyQt5 import QtGui, QtCore
from pyqtgraph.dockarea import *
class DockArea(DockArea):
## This is to prevent the Dock from being resized to te point of disappear
def makeContainer(self, typ):
new = super(DockArea, self).makeContainer(typ)
new.setChildrenCollapsible(False)
return new
class MyApp(QtGui.QMainWindow):
def __init__(self):
QtGui.QMainWindow.__init__(self)
central_widget = QtGui.QWidget()
layout = QtGui.QVBoxLayout()
central_widget.setLayout(layout)
self.setCentralWidget(central_widget)
label = QtGui.QLabel('This is a label, The widgets will be below')
label.setMaximumHeight(15)
## The DockArea as its name says, is the are where we place the Docks
dock_area = DockArea(self)
## Create the Docks and change some esthetic of them
self.dock1 = Dock('Widget 1', size=(300, 500))
self.dock2 = Dock('Widget 2', size=(400, 500))
self.dock1.hideTitleBar()
self.dock2.hideTitleBar()
self.dock1.nStyle = """
Dock > QWidget {
border: 0px solid #000;
border-radius: 0px;
}"""
self.dock2.nStyle = """
Dock > QWidget {
border: 0px solid #000;
border-radius: 0px;
}"""
self.button = QtGui.QPushButton('Exit')
self.widget_one = WidgetOne()
self.widget_two = WidgetTwo()
## Place the Docks inside the DockArea
dock_area.addDock(self.dock1)
dock_area.addDock(self.dock2, 'right', self.dock1)
## The statment above means that dock2 will be placed at the right of dock 1
layout.addWidget(label)
layout.addWidget(dock_area)
layout.addWidget(self.button)
## Add the Widgets inside each dock
self.dock1.addWidget(self.widget_one)
self.dock2.addWidget(self.widget_two)
## This is for set the initial size and posotion of the main window
self.setGeometry(100, 100, 600, 400)
## Connect the actions to functions, there is a default function called close()
self.widget_one.TitleClicked.connect(self.dob_click)
self.button.clicked.connect(self.close)
def dob_click(self, feed):
self.widget_two.text_box.clear()
## May look messy but wat i am doing is somethin like this:
## 'Title : ' + feed[0] + '\n\n' + 'Summary : ' + feed[1]
self.widget_two.text_box.setText(
'Title : ' + feed[0]\
+ '\n\n' +\
'Summary : ' + feed[1]
)
class WidgetOne(QtGui.QWidget):
## This signal is created to pass a "list" when it (the signal) is emited
TitleClicked = QtCore.pyqtSignal([list])
def __init__(self):
QtGui.QWidget.__init__(self)
self.layout = QtGui.QVBoxLayout()
self.setLayout(self.layout)
self.titleList = QtGui.QListWidget()
self.label = QtGui.QLabel('Here is my list:')
self.layout.addWidget(self.label)
self.layout.addWidget(self.titleList)
self.titleList.addItem(QtGui.QListWidgetItem('Title 1'))
self.titleList.addItem(QtGui.QListWidgetItem('Title 2'))
self.titleList.itemDoubleClicked.connect(self.onClicked)
def onClicked(self, item):
## Just test values
title = item.text()
summary = "Here you will put the summary of {}. ".format(title)*50
## Pass the values as a list in the signal. You can pass as much values
## as you want, remember that all of them have to be inside one list
self.TitleClicked.emit([title, summary])
class WidgetTwo(QtGui.QWidget):
def __init__(self):
QtGui.QWidget.__init__(self)
self.layout = QtGui.QVBoxLayout()
self.setLayout(self.layout)
self.label2 = QtGui.QLabel('Here we show results?:')
self.text_box = QtGui.QTextBrowser()
self.layout.addWidget(self.label2)
self.layout.addWidget(self.text_box)
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
window = MyApp()
window.show()
sys.exit(app.exec_())
Again, there are comments inside the code to help you understand what I did. Here is how it looks:
If you pass the mouse between the two widgets you will see the mouse icon will change, with that you can readjust on the run the size of both widgets.
Final Words
This is another approach, more "interactive" and more esthetic than my previous answer. As you said, using a QSplitter
works too.
这篇关于如何在一个主窗口中有两个小部件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!