我对 wxWidgets 和 C++ 很陌生,但我熟悉其他工具包。我想要这样的布局:
这就是它的样子。看起来好像我的窗口根本没有宽度:
这是我的代码,带有大量注释。
这是我的代码,我相信它已尽可能接近意图。 设计是这样的,每个“发件人”、“发件人”和“消息”都位于一个基于可重用面板的独特 block 中:
//CONTENTS OF GUI_MESSAGE_ITEM.H
#ifndef GUIMESSAGEITEM_H
#define GUIMESSAGEITEM_H
#include "wx/panel.h" // Base class: wxPanel
#include "wx/stattext.h"
#include "sms_message.h"
#include "wx/window.h"
#include "wx/wx.h"
class GUIMessageItem : public wxPanel {
public:
GUIMessageItem(wxWindow* parent, wxWindowID winid, const SMSMessage& smsMessage);
~GUIMessageItem();
private:
wxStaticText* stSender;
wxStaticText* stSentTime;
wxStaticText* stMessageContents;
};
#endif // GUIMESSAGEITEM_H
//CONTENTS OF GUI_MESSAGE_ITEM.CPP
#include "gui_message_item.h"
GUIMessageItem::GUIMessageItem(wxWindow* parent, wxWindowID winid, const SMSMessage& smsMessage) :
wxPanel(parent, winid),
stSender(new wxStaticText(this, winid, smsMessage.GetSender())),
stSentTime(new wxStaticText(this, winid, smsMessage.GetSentTime())),
stMessageContents(new wxStaticText(this, winid, smsMessage.GetMessage()))
{
wxColour blue(wxT("#2A2AF7"));
wxColour green(wxT("#56DB4F"));
wxFont originalFont = stSender->GetFont();
wxFont boldFont(originalFont);
boldFont.SetWeight( wxFONTWEIGHT_BOLD );
wxSize stsMin(100, 60);
wxSize bodyMin(300, 100);
stSender->SetForegroundColour(blue);
stSentTime->SetForegroundColour(green);
stSender->SetFont(boldFont);
stSentTime->SetFont(boldFont);
stSender->SetMinSize(stsMin);
stSentTime->SetMinSize(stsMin);
stMessageContents->SetMinSize(bodyMin);
stMessageContents->Wrap(200);
wxBoxSizer* lines = new wxBoxSizer( wxVERTICAL );
wxBoxSizer* topLine = new wxBoxSizer( wxHORIZONTAL );
lines->AddSpacer(4);
topLine->AddSpacer(5);
this->SetSizer(lines);
topLine->Add(stSender, wxALIGN_LEFT);
topLine->Add(stSentTime, wxALIGN_RIGHT);
lines->Add(topLine);
lines->Add(stMessageContents, wxALIGN_CENTER_HORIZONTAL );
lines->SetMinSize(wxSize(400,400));
this->FitInside();
this->Layout();
}
GUIMessageItem::~GUIMessageItem()
{
}
//MAIN CODE FOR THE WHOLE FORM
MainFrameBase::MainFrameBase( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxFrame( parent, id, title, pos, size, style )
{
this->SetSizeHints( wxDefaultSize, wxDefaultSize );
//Menu Bar stuff.
m_menuBar = new wxMenuBar( 0 );
m_menuFile = new wxMenu();
wxMenuItem* menuFileExit;
menuFileExit = new wxMenuItem( m_menuFile, wxID_EXIT, wxString( _("E&xit") ) + wxT('\t') + wxT("Alt+X"), wxEmptyString, wxITEM_NORMAL );
wxMenuItem* menuFileOpen;
menuFileOpen = new wxMenuItem( m_menuFile, wxID_OPEN, wxString( _("&Open") ) + wxT('\t') + wxT("Alt+O"), wxEmptyString, wxITEM_NORMAL );
m_menuFile->Append( menuFileOpen );
m_menuFile->Append( menuFileExit );
m_menuBar->Append( m_menuFile, _("&File") );
this->SetMenuBar( m_menuBar );
//main sizer for whole interface
wxBoxSizer* mainSizer = new wxBoxSizer( wxVERTICAL );
this->SetSizer( mainSizer );
// Filter box section
wxStaticText* filterLabel = new wxStaticText(this, wxID_ANY, wxT("Filter by Sender:"));
m_filter = new wxComboBox(
this,
wxID_ANY,
wxT(""),
wxDefaultPosition,
wxDefaultSize,
0,
NULL,
wxCB_DROPDOWN|wxCB_READONLY
);
wxBoxSizer* filterSizer = new wxBoxSizer( wxHORIZONTAL );
filterSizer->Add(filterLabel);
filterSizer->Add(m_filter);
mainSizer->Add(filterSizer);
// List of Messages section //The issue must be here somewhere...
m_scrWin = new wxScrolledWindow(
this,
wxID_ANY
);
m_listSizer = new wxBoxSizer(wxVERTICAL);
m_scrWin->SetSizer(m_listSizer);
mainSizer->Add(m_scrWin, wxEXPAND); //m_scrWin should take the WHOLE of the interface.
//example msg
SMSMessage* exampleMessage = new SMSMessage(
wxT("+44 07950 322 789"),
wxT("2011-13-07 13:22"),
wxT("Yo mate, what's up?")
);
for (int i = 0; i < 6; i++) {
AddSMSMessagePanel(*exampleMessage);
}
//wxSize minimum(300,500);
m_scrWin->FitInside(); //Use fit inside to make the scrollwindow use the width of the items inside? without doing this I get no scrollbar at all...
//m_scrWin->SetMinSize(minimum);
//m_listSizer->SetMinSize(minimum);
//m_scrWin->EnableScrolling(true, true);
//m_scrWin->SetScrollRate(1,1);
m_scrWin->SetScrollRate(5, 5);
this->Layout();
m_statusBar = this->CreateStatusBar( 1, wxST_SIZEGRIP, wxID_ANY );
this->Centre( wxBOTH );
// Connect Events
this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( MainFrameBase::OnCloseFrame ) );
this->Connect( menuFileOpen->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnFileOpen ) );
this->Connect( menuFileExit->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnExitClick ) );
}
void MainFrameBase::AddSMSMessagePanel(const SMSMessage& message) {
GUIMessageItem* gmi = new GUIMessageItem(m_scrWin, wxID_ANY, message); //object inherits from wxPanel
m_listSizer->Add(gmi);
}
我很抱歉在这里提出这样的具体问题,但我是 C++ 和 wxWidgets 的新手,我已经花了大约 5 个小时试图解决这个问题,但我没有 知道我缺乏什么知识。
这是完整源代码的链接:https://github.com/PhillipTaylor/SMSReader
最佳答案
有很多代码要看,我不会假装明白发生了什么。
据我所知,您正在编写和调试大量代码,这些代码都可以使用 wxGrid 替换。使用 wxGrid 会使事情变得简单得多,所有棘手的事情都已经为您测试和调试过了。
关于C++ wxWidgets - 没有宽度的 ScrolledWindow 的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8727590/